1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * security/tomoyo/common.c 4 * 5 * Copyright (C) 2005-2011 NTT DATA CORPORATION 6 */ 7 8 #include <linux/uaccess.h> 9 #include <linux/slab.h> 10 #include <linux/security.h> 11 #include <linux/string_helpers.h> 12 #include "common.h" 13 14 /* String table for operation mode. */ 15 const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = { 16 [TOMOYO_CONFIG_DISABLED] = "disabled", 17 [TOMOYO_CONFIG_LEARNING] = "learning", 18 [TOMOYO_CONFIG_PERMISSIVE] = "permissive", 19 [TOMOYO_CONFIG_ENFORCING] = "enforcing" 20 }; 21 22 /* String table for /sys/kernel/security/tomoyo/profile */ 23 const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 24 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 25 /* CONFIG::file group */ 26 [TOMOYO_MAC_FILE_EXECUTE] = "execute", 27 [TOMOYO_MAC_FILE_OPEN] = "open", 28 [TOMOYO_MAC_FILE_CREATE] = "create", 29 [TOMOYO_MAC_FILE_UNLINK] = "unlink", 30 [TOMOYO_MAC_FILE_GETATTR] = "getattr", 31 [TOMOYO_MAC_FILE_MKDIR] = "mkdir", 32 [TOMOYO_MAC_FILE_RMDIR] = "rmdir", 33 [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo", 34 [TOMOYO_MAC_FILE_MKSOCK] = "mksock", 35 [TOMOYO_MAC_FILE_TRUNCATE] = "truncate", 36 [TOMOYO_MAC_FILE_SYMLINK] = "symlink", 37 [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock", 38 [TOMOYO_MAC_FILE_MKCHAR] = "mkchar", 39 [TOMOYO_MAC_FILE_LINK] = "link", 40 [TOMOYO_MAC_FILE_RENAME] = "rename", 41 [TOMOYO_MAC_FILE_CHMOD] = "chmod", 42 [TOMOYO_MAC_FILE_CHOWN] = "chown", 43 [TOMOYO_MAC_FILE_CHGRP] = "chgrp", 44 [TOMOYO_MAC_FILE_IOCTL] = "ioctl", 45 [TOMOYO_MAC_FILE_CHROOT] = "chroot", 46 [TOMOYO_MAC_FILE_MOUNT] = "mount", 47 [TOMOYO_MAC_FILE_UMOUNT] = "unmount", 48 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", 49 /* CONFIG::network group */ 50 [TOMOYO_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind", 51 [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen", 52 [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect", 53 [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind", 54 [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send", 55 [TOMOYO_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind", 56 [TOMOYO_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send", 57 [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind", 58 [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen", 59 [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect", 60 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind", 61 [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send", 62 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind", 63 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen", 64 [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect", 65 /* CONFIG::misc group */ 66 [TOMOYO_MAC_ENVIRON] = "env", 67 /* CONFIG group */ 68 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", 69 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network", 70 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc", 71 }; 72 73 /* String table for conditions. */ 74 const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = { 75 [TOMOYO_TASK_UID] = "task.uid", 76 [TOMOYO_TASK_EUID] = "task.euid", 77 [TOMOYO_TASK_SUID] = "task.suid", 78 [TOMOYO_TASK_FSUID] = "task.fsuid", 79 [TOMOYO_TASK_GID] = "task.gid", 80 [TOMOYO_TASK_EGID] = "task.egid", 81 [TOMOYO_TASK_SGID] = "task.sgid", 82 [TOMOYO_TASK_FSGID] = "task.fsgid", 83 [TOMOYO_TASK_PID] = "task.pid", 84 [TOMOYO_TASK_PPID] = "task.ppid", 85 [TOMOYO_EXEC_ARGC] = "exec.argc", 86 [TOMOYO_EXEC_ENVC] = "exec.envc", 87 [TOMOYO_TYPE_IS_SOCKET] = "socket", 88 [TOMOYO_TYPE_IS_SYMLINK] = "symlink", 89 [TOMOYO_TYPE_IS_FILE] = "file", 90 [TOMOYO_TYPE_IS_BLOCK_DEV] = "block", 91 [TOMOYO_TYPE_IS_DIRECTORY] = "directory", 92 [TOMOYO_TYPE_IS_CHAR_DEV] = "char", 93 [TOMOYO_TYPE_IS_FIFO] = "fifo", 94 [TOMOYO_MODE_SETUID] = "setuid", 95 [TOMOYO_MODE_SETGID] = "setgid", 96 [TOMOYO_MODE_STICKY] = "sticky", 97 [TOMOYO_MODE_OWNER_READ] = "owner_read", 98 [TOMOYO_MODE_OWNER_WRITE] = "owner_write", 99 [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute", 100 [TOMOYO_MODE_GROUP_READ] = "group_read", 101 [TOMOYO_MODE_GROUP_WRITE] = "group_write", 102 [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute", 103 [TOMOYO_MODE_OTHERS_READ] = "others_read", 104 [TOMOYO_MODE_OTHERS_WRITE] = "others_write", 105 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", 106 [TOMOYO_EXEC_REALPATH] = "exec.realpath", 107 [TOMOYO_SYMLINK_TARGET] = "symlink.target", 108 [TOMOYO_PATH1_UID] = "path1.uid", 109 [TOMOYO_PATH1_GID] = "path1.gid", 110 [TOMOYO_PATH1_INO] = "path1.ino", 111 [TOMOYO_PATH1_MAJOR] = "path1.major", 112 [TOMOYO_PATH1_MINOR] = "path1.minor", 113 [TOMOYO_PATH1_PERM] = "path1.perm", 114 [TOMOYO_PATH1_TYPE] = "path1.type", 115 [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major", 116 [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor", 117 [TOMOYO_PATH2_UID] = "path2.uid", 118 [TOMOYO_PATH2_GID] = "path2.gid", 119 [TOMOYO_PATH2_INO] = "path2.ino", 120 [TOMOYO_PATH2_MAJOR] = "path2.major", 121 [TOMOYO_PATH2_MINOR] = "path2.minor", 122 [TOMOYO_PATH2_PERM] = "path2.perm", 123 [TOMOYO_PATH2_TYPE] = "path2.type", 124 [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major", 125 [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor", 126 [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid", 127 [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid", 128 [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino", 129 [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm", 130 [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid", 131 [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid", 132 [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino", 133 [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm", 134 }; 135 136 /* String table for PREFERENCE keyword. */ 137 static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = { 138 [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log", 139 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry", 140 }; 141 142 /* String table for path operation. */ 143 const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 144 [TOMOYO_TYPE_EXECUTE] = "execute", 145 [TOMOYO_TYPE_READ] = "read", 146 [TOMOYO_TYPE_WRITE] = "write", 147 [TOMOYO_TYPE_APPEND] = "append", 148 [TOMOYO_TYPE_UNLINK] = "unlink", 149 [TOMOYO_TYPE_GETATTR] = "getattr", 150 [TOMOYO_TYPE_RMDIR] = "rmdir", 151 [TOMOYO_TYPE_TRUNCATE] = "truncate", 152 [TOMOYO_TYPE_SYMLINK] = "symlink", 153 [TOMOYO_TYPE_CHROOT] = "chroot", 154 [TOMOYO_TYPE_UMOUNT] = "unmount", 155 }; 156 157 /* String table for socket's operation. */ 158 const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = { 159 [TOMOYO_NETWORK_BIND] = "bind", 160 [TOMOYO_NETWORK_LISTEN] = "listen", 161 [TOMOYO_NETWORK_CONNECT] = "connect", 162 [TOMOYO_NETWORK_SEND] = "send", 163 }; 164 165 /* String table for categories. */ 166 static const char * const tomoyo_category_keywords 167 [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 168 [TOMOYO_MAC_CATEGORY_FILE] = "file", 169 [TOMOYO_MAC_CATEGORY_NETWORK] = "network", 170 [TOMOYO_MAC_CATEGORY_MISC] = "misc", 171 }; 172 173 /* Permit policy management by non-root user? */ 174 static bool tomoyo_manage_by_non_root; 175 176 /* Utility functions. */ 177 178 /** 179 * tomoyo_addprintf - strncat()-like-snprintf(). 180 * 181 * @buffer: Buffer to write to. Must be '\0'-terminated. 182 * @len: Size of @buffer. 183 * @fmt: The printf()'s format string, followed by parameters. 184 * 185 * Returns nothing. 186 */ 187 __printf(3, 4) 188 static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) 189 { 190 va_list args; 191 const int pos = strlen(buffer); 192 193 va_start(args, fmt); 194 vsnprintf(buffer + pos, len - pos - 1, fmt, args); 195 va_end(args); 196 } 197 198 /** 199 * tomoyo_flush - Flush queued string to userspace's buffer. 200 * 201 * @head: Pointer to "struct tomoyo_io_buffer". 202 * 203 * Returns true if all data was flushed, false otherwise. 204 */ 205 static bool tomoyo_flush(struct tomoyo_io_buffer *head) 206 { 207 while (head->r.w_pos) { 208 const char *w = head->r.w[0]; 209 size_t len = strlen(w); 210 211 if (len) { 212 if (len > head->read_user_buf_avail) 213 len = head->read_user_buf_avail; 214 if (!len) 215 return false; 216 if (copy_to_user(head->read_user_buf, w, len)) 217 return false; 218 head->read_user_buf_avail -= len; 219 head->read_user_buf += len; 220 w += len; 221 } 222 head->r.w[0] = w; 223 if (*w) 224 return false; 225 /* Add '\0' for audit logs and query. */ 226 if (head->poll) { 227 if (!head->read_user_buf_avail || 228 copy_to_user(head->read_user_buf, "", 1)) 229 return false; 230 head->read_user_buf_avail--; 231 head->read_user_buf++; 232 } 233 head->r.w_pos--; 234 for (len = 0; len < head->r.w_pos; len++) 235 head->r.w[len] = head->r.w[len + 1]; 236 } 237 head->r.avail = 0; 238 return true; 239 } 240 241 /** 242 * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure. 243 * 244 * @head: Pointer to "struct tomoyo_io_buffer". 245 * @string: String to print. 246 * 247 * Note that @string has to be kept valid until @head is kfree()d. 248 * This means that char[] allocated on stack memory cannot be passed to 249 * this function. Use tomoyo_io_printf() for char[] allocated on stack memory. 250 */ 251 static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string) 252 { 253 if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) { 254 head->r.w[head->r.w_pos++] = string; 255 tomoyo_flush(head); 256 } else 257 WARN_ON(1); 258 } 259 260 static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, 261 ...) __printf(2, 3); 262 263 /** 264 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. 265 * 266 * @head: Pointer to "struct tomoyo_io_buffer". 267 * @fmt: The printf()'s format string, followed by parameters. 268 */ 269 static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, 270 ...) 271 { 272 va_list args; 273 size_t len; 274 size_t pos = head->r.avail; 275 int size = head->readbuf_size - pos; 276 277 if (size <= 0) 278 return; 279 va_start(args, fmt); 280 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; 281 va_end(args); 282 if (pos + len >= head->readbuf_size) { 283 WARN_ON(1); 284 return; 285 } 286 head->r.avail += len; 287 tomoyo_set_string(head, head->read_buf + pos); 288 } 289 290 /** 291 * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure. 292 * 293 * @head: Pointer to "struct tomoyo_io_buffer". 294 * 295 * Returns nothing. 296 */ 297 static void tomoyo_set_space(struct tomoyo_io_buffer *head) 298 { 299 tomoyo_set_string(head, " "); 300 } 301 302 /** 303 * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure. 304 * 305 * @head: Pointer to "struct tomoyo_io_buffer". 306 * 307 * Returns nothing. 308 */ 309 static bool tomoyo_set_lf(struct tomoyo_io_buffer *head) 310 { 311 tomoyo_set_string(head, "\n"); 312 return !head->r.w_pos; 313 } 314 315 /** 316 * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure. 317 * 318 * @head: Pointer to "struct tomoyo_io_buffer". 319 * 320 * Returns nothing. 321 */ 322 static void tomoyo_set_slash(struct tomoyo_io_buffer *head) 323 { 324 tomoyo_set_string(head, "/"); 325 } 326 327 /* List of namespaces. */ 328 LIST_HEAD(tomoyo_namespace_list); 329 /* True if namespace other than tomoyo_kernel_namespace is defined. */ 330 static bool tomoyo_namespace_enabled; 331 332 /** 333 * tomoyo_init_policy_namespace - Initialize namespace. 334 * 335 * @ns: Pointer to "struct tomoyo_policy_namespace". 336 * 337 * Returns nothing. 338 */ 339 void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) 340 { 341 unsigned int idx; 342 343 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) 344 INIT_LIST_HEAD(&ns->acl_group[idx]); 345 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++) 346 INIT_LIST_HEAD(&ns->group_list[idx]); 347 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) 348 INIT_LIST_HEAD(&ns->policy_list[idx]); 349 ns->profile_version = 20150505; 350 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); 351 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); 352 } 353 354 /** 355 * tomoyo_print_namespace - Print namespace header. 356 * 357 * @head: Pointer to "struct tomoyo_io_buffer". 358 * 359 * Returns nothing. 360 */ 361 static void tomoyo_print_namespace(struct tomoyo_io_buffer *head) 362 { 363 if (!tomoyo_namespace_enabled) 364 return; 365 tomoyo_set_string(head, 366 container_of(head->r.ns, 367 struct tomoyo_policy_namespace, 368 namespace_list)->name); 369 tomoyo_set_space(head); 370 } 371 372 /** 373 * tomoyo_print_name_union - Print a tomoyo_name_union. 374 * 375 * @head: Pointer to "struct tomoyo_io_buffer". 376 * @ptr: Pointer to "struct tomoyo_name_union". 377 */ 378 static void tomoyo_print_name_union(struct tomoyo_io_buffer *head, 379 const struct tomoyo_name_union *ptr) 380 { 381 tomoyo_set_space(head); 382 if (ptr->group) { 383 tomoyo_set_string(head, "@"); 384 tomoyo_set_string(head, ptr->group->group_name->name); 385 } else { 386 tomoyo_set_string(head, ptr->filename->name); 387 } 388 } 389 390 /** 391 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote. 392 * 393 * @head: Pointer to "struct tomoyo_io_buffer". 394 * @ptr: Pointer to "struct tomoyo_name_union". 395 * 396 * Returns nothing. 397 */ 398 static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head, 399 const struct tomoyo_name_union *ptr) 400 { 401 if (ptr->group) { 402 tomoyo_set_string(head, "@"); 403 tomoyo_set_string(head, ptr->group->group_name->name); 404 } else { 405 tomoyo_set_string(head, "\""); 406 tomoyo_set_string(head, ptr->filename->name); 407 tomoyo_set_string(head, "\""); 408 } 409 } 410 411 /** 412 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. 413 * 414 * @head: Pointer to "struct tomoyo_io_buffer". 415 * @ptr: Pointer to "struct tomoyo_number_union". 416 * 417 * Returns nothing. 418 */ 419 static void tomoyo_print_number_union_nospace 420 (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr) 421 { 422 if (ptr->group) { 423 tomoyo_set_string(head, "@"); 424 tomoyo_set_string(head, ptr->group->group_name->name); 425 } else { 426 int i; 427 unsigned long min = ptr->values[0]; 428 const unsigned long max = ptr->values[1]; 429 u8 min_type = ptr->value_type[0]; 430 const u8 max_type = ptr->value_type[1]; 431 char buffer[128]; 432 433 buffer[0] = '\0'; 434 for (i = 0; i < 2; i++) { 435 switch (min_type) { 436 case TOMOYO_VALUE_TYPE_HEXADECIMAL: 437 tomoyo_addprintf(buffer, sizeof(buffer), 438 "0x%lX", min); 439 break; 440 case TOMOYO_VALUE_TYPE_OCTAL: 441 tomoyo_addprintf(buffer, sizeof(buffer), 442 "0%lo", min); 443 break; 444 default: 445 tomoyo_addprintf(buffer, sizeof(buffer), "%lu", 446 min); 447 break; 448 } 449 if (min == max && min_type == max_type) 450 break; 451 tomoyo_addprintf(buffer, sizeof(buffer), "-"); 452 min_type = max_type; 453 min = max; 454 } 455 tomoyo_io_printf(head, "%s", buffer); 456 } 457 } 458 459 /** 460 * tomoyo_print_number_union - Print a tomoyo_number_union. 461 * 462 * @head: Pointer to "struct tomoyo_io_buffer". 463 * @ptr: Pointer to "struct tomoyo_number_union". 464 * 465 * Returns nothing. 466 */ 467 static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, 468 const struct tomoyo_number_union *ptr) 469 { 470 tomoyo_set_space(head); 471 tomoyo_print_number_union_nospace(head, ptr); 472 } 473 474 /** 475 * tomoyo_assign_profile - Create a new profile. 476 * 477 * @ns: Pointer to "struct tomoyo_policy_namespace". 478 * @profile: Profile number to create. 479 * 480 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 481 */ 482 static struct tomoyo_profile *tomoyo_assign_profile 483 (struct tomoyo_policy_namespace *ns, const unsigned int profile) 484 { 485 struct tomoyo_profile *ptr; 486 struct tomoyo_profile *entry; 487 488 if (profile >= TOMOYO_MAX_PROFILES) 489 return NULL; 490 ptr = ns->profile_ptr[profile]; 491 if (ptr) 492 return ptr; 493 entry = kzalloc(sizeof(*entry), GFP_NOFS | __GFP_NOWARN); 494 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 495 goto out; 496 ptr = ns->profile_ptr[profile]; 497 if (!ptr && tomoyo_memory_ok(entry)) { 498 ptr = entry; 499 ptr->default_config = TOMOYO_CONFIG_DISABLED | 500 TOMOYO_CONFIG_WANT_GRANT_LOG | 501 TOMOYO_CONFIG_WANT_REJECT_LOG; 502 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 503 sizeof(ptr->config)); 504 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 505 CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG; 506 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 507 CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY; 508 mb(); /* Avoid out-of-order execution. */ 509 ns->profile_ptr[profile] = ptr; 510 entry = NULL; 511 } 512 mutex_unlock(&tomoyo_policy_lock); 513 out: 514 kfree(entry); 515 return ptr; 516 } 517 518 /** 519 * tomoyo_profile - Find a profile. 520 * 521 * @ns: Pointer to "struct tomoyo_policy_namespace". 522 * @profile: Profile number to find. 523 * 524 * Returns pointer to "struct tomoyo_profile". 525 */ 526 struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns, 527 const u8 profile) 528 { 529 static struct tomoyo_profile tomoyo_null_profile; 530 struct tomoyo_profile *ptr = ns->profile_ptr[profile]; 531 532 if (!ptr) 533 ptr = &tomoyo_null_profile; 534 return ptr; 535 } 536 537 /** 538 * tomoyo_find_yesno - Find values for specified keyword. 539 * 540 * @string: String to check. 541 * @find: Name of keyword. 542 * 543 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise. 544 */ 545 static s8 tomoyo_find_yesno(const char *string, const char *find) 546 { 547 const char *cp = strstr(string, find); 548 549 if (cp) { 550 cp += strlen(find); 551 if (!strncmp(cp, "=yes", 4)) 552 return 1; 553 else if (!strncmp(cp, "=no", 3)) 554 return 0; 555 } 556 return -1; 557 } 558 559 /** 560 * tomoyo_set_uint - Set value for specified preference. 561 * 562 * @i: Pointer to "unsigned int". 563 * @string: String to check. 564 * @find: Name of keyword. 565 * 566 * Returns nothing. 567 */ 568 static void tomoyo_set_uint(unsigned int *i, const char *string, 569 const char *find) 570 { 571 const char *cp = strstr(string, find); 572 573 if (cp) 574 sscanf(cp + strlen(find), "=%u", i); 575 } 576 577 /** 578 * tomoyo_set_mode - Set mode for specified profile. 579 * 580 * @name: Name of functionality. 581 * @value: Mode for @name. 582 * @profile: Pointer to "struct tomoyo_profile". 583 * 584 * Returns 0 on success, negative value otherwise. 585 */ 586 static int tomoyo_set_mode(char *name, const char *value, 587 struct tomoyo_profile *profile) 588 { 589 u8 i; 590 u8 config; 591 592 if (!strcmp(name, "CONFIG")) { 593 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; 594 config = profile->default_config; 595 } else if (tomoyo_str_starts(&name, "CONFIG::")) { 596 config = 0; 597 for (i = 0; i < TOMOYO_MAX_MAC_INDEX 598 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { 599 int len = 0; 600 601 if (i < TOMOYO_MAX_MAC_INDEX) { 602 const u8 c = tomoyo_index2category[i]; 603 const char *category = 604 tomoyo_category_keywords[c]; 605 606 len = strlen(category); 607 if (strncmp(name, category, len) || 608 name[len++] != ':' || name[len++] != ':') 609 continue; 610 } 611 if (strcmp(name + len, tomoyo_mac_keywords[i])) 612 continue; 613 config = profile->config[i]; 614 break; 615 } 616 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 617 return -EINVAL; 618 } else { 619 return -EINVAL; 620 } 621 if (strstr(value, "use_default")) { 622 config = TOMOYO_CONFIG_USE_DEFAULT; 623 } else { 624 u8 mode; 625 626 for (mode = 0; mode < 4; mode++) 627 if (strstr(value, tomoyo_mode[mode])) 628 /* 629 * Update lower 3 bits in order to distinguish 630 * 'config' from 'TOMOYO_CONFIG_USE_DEFAULT'. 631 */ 632 config = (config & ~7) | mode; 633 if (config != TOMOYO_CONFIG_USE_DEFAULT) { 634 switch (tomoyo_find_yesno(value, "grant_log")) { 635 case 1: 636 config |= TOMOYO_CONFIG_WANT_GRANT_LOG; 637 break; 638 case 0: 639 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG; 640 break; 641 } 642 switch (tomoyo_find_yesno(value, "reject_log")) { 643 case 1: 644 config |= TOMOYO_CONFIG_WANT_REJECT_LOG; 645 break; 646 case 0: 647 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG; 648 break; 649 } 650 } 651 } 652 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 653 profile->config[i] = config; 654 else if (config != TOMOYO_CONFIG_USE_DEFAULT) 655 profile->default_config = config; 656 return 0; 657 } 658 659 /** 660 * tomoyo_write_profile - Write profile table. 661 * 662 * @head: Pointer to "struct tomoyo_io_buffer". 663 * 664 * Returns 0 on success, negative value otherwise. 665 */ 666 static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 667 { 668 char *data = head->write_buf; 669 unsigned int i; 670 char *cp; 671 struct tomoyo_profile *profile; 672 673 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) 674 == 1) 675 return 0; 676 i = simple_strtoul(data, &cp, 10); 677 if (*cp != '-') 678 return -EINVAL; 679 data = cp + 1; 680 profile = tomoyo_assign_profile(head->w.ns, i); 681 if (!profile) 682 return -EINVAL; 683 cp = strchr(data, '='); 684 if (!cp) 685 return -EINVAL; 686 *cp++ = '\0'; 687 if (!strcmp(data, "COMMENT")) { 688 static DEFINE_SPINLOCK(lock); 689 const struct tomoyo_path_info *new_comment 690 = tomoyo_get_name(cp); 691 const struct tomoyo_path_info *old_comment; 692 693 if (!new_comment) 694 return -ENOMEM; 695 spin_lock(&lock); 696 old_comment = profile->comment; 697 profile->comment = new_comment; 698 spin_unlock(&lock); 699 tomoyo_put_name(old_comment); 700 return 0; 701 } 702 if (!strcmp(data, "PREFERENCE")) { 703 for (i = 0; i < TOMOYO_MAX_PREF; i++) 704 tomoyo_set_uint(&profile->pref[i], cp, 705 tomoyo_pref_keywords[i]); 706 return 0; 707 } 708 return tomoyo_set_mode(data, cp, profile); 709 } 710 711 /** 712 * tomoyo_print_config - Print mode for specified functionality. 713 * 714 * @head: Pointer to "struct tomoyo_io_buffer". 715 * @config: Mode for that functionality. 716 * 717 * Returns nothing. 718 * 719 * Caller prints functionality's name. 720 */ 721 static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 722 { 723 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n", 724 tomoyo_mode[config & 3], 725 str_yes_no(config & TOMOYO_CONFIG_WANT_GRANT_LOG), 726 str_yes_no(config & TOMOYO_CONFIG_WANT_REJECT_LOG)); 727 } 728 729 /** 730 * tomoyo_read_profile - Read profile table. 731 * 732 * @head: Pointer to "struct tomoyo_io_buffer". 733 * 734 * Returns nothing. 735 */ 736 static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 737 { 738 u8 index; 739 struct tomoyo_policy_namespace *ns = 740 container_of(head->r.ns, typeof(*ns), namespace_list); 741 const struct tomoyo_profile *profile; 742 743 if (head->r.eof) 744 return; 745 next: 746 index = head->r.index; 747 profile = ns->profile_ptr[index]; 748 switch (head->r.step) { 749 case 0: 750 tomoyo_print_namespace(head); 751 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n", 752 ns->profile_version); 753 head->r.step++; 754 break; 755 case 1: 756 for ( ; head->r.index < TOMOYO_MAX_PROFILES; 757 head->r.index++) 758 if (ns->profile_ptr[head->r.index]) 759 break; 760 if (head->r.index == TOMOYO_MAX_PROFILES) { 761 head->r.eof = true; 762 return; 763 } 764 head->r.step++; 765 break; 766 case 2: 767 { 768 u8 i; 769 const struct tomoyo_path_info *comment = 770 profile->comment; 771 772 tomoyo_print_namespace(head); 773 tomoyo_io_printf(head, "%u-COMMENT=", index); 774 tomoyo_set_string(head, comment ? comment->name : ""); 775 tomoyo_set_lf(head); 776 tomoyo_print_namespace(head); 777 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index); 778 for (i = 0; i < TOMOYO_MAX_PREF; i++) 779 tomoyo_io_printf(head, "%s=%u ", 780 tomoyo_pref_keywords[i], 781 profile->pref[i]); 782 tomoyo_set_string(head, "}\n"); 783 head->r.step++; 784 } 785 break; 786 case 3: 787 { 788 tomoyo_print_namespace(head); 789 tomoyo_io_printf(head, "%u-%s", index, "CONFIG"); 790 tomoyo_print_config(head, profile->default_config); 791 head->r.bit = 0; 792 head->r.step++; 793 } 794 break; 795 case 4: 796 for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX 797 + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { 798 const u8 i = head->r.bit; 799 const u8 config = profile->config[i]; 800 801 if (config == TOMOYO_CONFIG_USE_DEFAULT) 802 continue; 803 tomoyo_print_namespace(head); 804 if (i < TOMOYO_MAX_MAC_INDEX) 805 tomoyo_io_printf(head, "%u-CONFIG::%s::%s", 806 index, 807 tomoyo_category_keywords 808 [tomoyo_index2category[i]], 809 tomoyo_mac_keywords[i]); 810 else 811 tomoyo_io_printf(head, "%u-CONFIG::%s", index, 812 tomoyo_mac_keywords[i]); 813 tomoyo_print_config(head, config); 814 head->r.bit++; 815 break; 816 } 817 if (head->r.bit == TOMOYO_MAX_MAC_INDEX 818 + TOMOYO_MAX_MAC_CATEGORY_INDEX) { 819 head->r.index++; 820 head->r.step = 1; 821 } 822 break; 823 } 824 if (tomoyo_flush(head)) 825 goto next; 826 } 827 828 /** 829 * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry. 830 * 831 * @a: Pointer to "struct tomoyo_acl_head". 832 * @b: Pointer to "struct tomoyo_acl_head". 833 * 834 * Returns true if @a == @b, false otherwise. 835 */ 836 static bool tomoyo_same_manager(const struct tomoyo_acl_head *a, 837 const struct tomoyo_acl_head *b) 838 { 839 return container_of(a, struct tomoyo_manager, head)->manager == 840 container_of(b, struct tomoyo_manager, head)->manager; 841 } 842 843 /** 844 * tomoyo_update_manager_entry - Add a manager entry. 845 * 846 * @manager: The path to manager or the domainnamme. 847 * @is_delete: True if it is a delete request. 848 * 849 * Returns 0 on success, negative value otherwise. 850 * 851 * Caller holds tomoyo_read_lock(). 852 */ 853 static int tomoyo_update_manager_entry(const char *manager, 854 const bool is_delete) 855 { 856 struct tomoyo_manager e = { }; 857 struct tomoyo_acl_param param = { 858 /* .ns = &tomoyo_kernel_namespace, */ 859 .is_delete = is_delete, 860 .list = &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], 861 }; 862 int error = is_delete ? -ENOENT : -ENOMEM; 863 864 if (!tomoyo_correct_domain(manager) && 865 !tomoyo_correct_word(manager)) 866 return -EINVAL; 867 e.manager = tomoyo_get_name(manager); 868 if (e.manager) { 869 error = tomoyo_update_policy(&e.head, sizeof(e), ¶m, 870 tomoyo_same_manager); 871 tomoyo_put_name(e.manager); 872 } 873 return error; 874 } 875 876 /** 877 * tomoyo_write_manager - Write manager policy. 878 * 879 * @head: Pointer to "struct tomoyo_io_buffer". 880 * 881 * Returns 0 on success, negative value otherwise. 882 * 883 * Caller holds tomoyo_read_lock(). 884 */ 885 static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 886 { 887 char *data = head->write_buf; 888 889 if (!strcmp(data, "manage_by_non_root")) { 890 tomoyo_manage_by_non_root = !head->w.is_delete; 891 return 0; 892 } 893 return tomoyo_update_manager_entry(data, head->w.is_delete); 894 } 895 896 /** 897 * tomoyo_read_manager - Read manager policy. 898 * 899 * @head: Pointer to "struct tomoyo_io_buffer". 900 * 901 * Caller holds tomoyo_read_lock(). 902 */ 903 static void tomoyo_read_manager(struct tomoyo_io_buffer *head) 904 { 905 if (head->r.eof) 906 return; 907 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER]) { 908 struct tomoyo_manager *ptr = 909 list_entry(head->r.acl, typeof(*ptr), head.list); 910 911 if (ptr->head.is_deleted) 912 continue; 913 if (!tomoyo_flush(head)) 914 return; 915 tomoyo_set_string(head, ptr->manager->name); 916 tomoyo_set_lf(head); 917 } 918 head->r.eof = true; 919 } 920 921 /** 922 * tomoyo_manager - Check whether the current process is a policy manager. 923 * 924 * Returns true if the current process is permitted to modify policy 925 * via /sys/kernel/security/tomoyo/ interface. 926 * 927 * Caller holds tomoyo_read_lock(). 928 */ 929 static bool tomoyo_manager(void) 930 { 931 struct tomoyo_manager *ptr; 932 const char *exe; 933 const struct task_struct *task = current; 934 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; 935 bool found = IS_ENABLED(CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING); 936 937 if (!tomoyo_policy_loaded) 938 return true; 939 if (!tomoyo_manage_by_non_root && 940 (!uid_eq(task->cred->uid, GLOBAL_ROOT_UID) || 941 !uid_eq(task->cred->euid, GLOBAL_ROOT_UID))) 942 return false; 943 exe = tomoyo_get_exe(); 944 if (!exe) 945 return false; 946 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list, 947 srcu_read_lock_held(&tomoyo_ss)) { 948 if (!ptr->head.is_deleted && 949 (!tomoyo_pathcmp(domainname, ptr->manager) || 950 !strcmp(exe, ptr->manager->name))) { 951 found = true; 952 break; 953 } 954 } 955 if (!found) { /* Reduce error messages. */ 956 static pid_t last_pid; 957 const pid_t pid = current->pid; 958 959 if (last_pid != pid) { 960 pr_warn("%s ( %s ) is not permitted to update policies.\n", 961 domainname->name, exe); 962 last_pid = pid; 963 } 964 } 965 kfree(exe); 966 return found; 967 } 968 969 static struct tomoyo_domain_info *tomoyo_find_domain_by_qid 970 (unsigned int serial); 971 972 /** 973 * tomoyo_select_domain - Parse select command. 974 * 975 * @head: Pointer to "struct tomoyo_io_buffer". 976 * @data: String to parse. 977 * 978 * Returns true on success, false otherwise. 979 * 980 * Caller holds tomoyo_read_lock(). 981 */ 982 static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, 983 const char *data) 984 { 985 unsigned int pid; 986 struct tomoyo_domain_info *domain = NULL; 987 bool global_pid = false; 988 989 if (strncmp(data, "select ", 7)) 990 return false; 991 data += 7; 992 if (sscanf(data, "pid=%u", &pid) == 1 || 993 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 994 struct task_struct *p; 995 996 rcu_read_lock(); 997 if (global_pid) 998 p = find_task_by_pid_ns(pid, &init_pid_ns); 999 else 1000 p = find_task_by_vpid(pid); 1001 if (p) 1002 domain = tomoyo_task(p)->domain_info; 1003 rcu_read_unlock(); 1004 } else if (!strncmp(data, "domain=", 7)) { 1005 if (tomoyo_domain_def(data + 7)) 1006 domain = tomoyo_find_domain(data + 7); 1007 } else if (sscanf(data, "Q=%u", &pid) == 1) { 1008 domain = tomoyo_find_domain_by_qid(pid); 1009 } else 1010 return false; 1011 head->w.domain = domain; 1012 /* Accessing read_buf is safe because head->io_sem is held. */ 1013 if (!head->read_buf) 1014 return true; /* Do nothing if open(O_WRONLY). */ 1015 memset(&head->r, 0, sizeof(head->r)); 1016 head->r.print_this_domain_only = true; 1017 if (domain) 1018 head->r.domain = &domain->list; 1019 else 1020 head->r.eof = true; 1021 tomoyo_io_printf(head, "# select %s\n", data); 1022 if (domain && domain->is_deleted) 1023 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 1024 return true; 1025 } 1026 1027 /** 1028 * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry. 1029 * 1030 * @a: Pointer to "struct tomoyo_acl_info". 1031 * @b: Pointer to "struct tomoyo_acl_info". 1032 * 1033 * Returns true if @a == @b, false otherwise. 1034 */ 1035 static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a, 1036 const struct tomoyo_acl_info *b) 1037 { 1038 const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head); 1039 const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head); 1040 1041 return p1->domainname == p2->domainname; 1042 } 1043 1044 /** 1045 * tomoyo_write_task - Update task related list. 1046 * 1047 * @param: Pointer to "struct tomoyo_acl_param". 1048 * 1049 * Returns 0 on success, negative value otherwise. 1050 * 1051 * Caller holds tomoyo_read_lock(). 1052 */ 1053 static int tomoyo_write_task(struct tomoyo_acl_param *param) 1054 { 1055 int error = -EINVAL; 1056 1057 if (tomoyo_str_starts(¶m->data, "manual_domain_transition ")) { 1058 struct tomoyo_task_acl e = { 1059 .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL, 1060 .domainname = tomoyo_get_domainname(param), 1061 }; 1062 1063 if (e.domainname) 1064 error = tomoyo_update_domain(&e.head, sizeof(e), param, 1065 tomoyo_same_task_acl, 1066 NULL); 1067 tomoyo_put_name(e.domainname); 1068 } 1069 return error; 1070 } 1071 1072 /** 1073 * tomoyo_delete_domain - Delete a domain. 1074 * 1075 * @domainname: The name of domain. 1076 * 1077 * Returns 0 on success, negative value otherwise. 1078 * 1079 * Caller holds tomoyo_read_lock(). 1080 */ 1081 static int tomoyo_delete_domain(char *domainname) 1082 { 1083 struct tomoyo_domain_info *domain; 1084 struct tomoyo_path_info name; 1085 1086 name.name = domainname; 1087 tomoyo_fill_path_info(&name); 1088 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1089 return -EINTR; 1090 /* Is there an active domain? */ 1091 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, 1092 srcu_read_lock_held(&tomoyo_ss)) { 1093 /* Never delete tomoyo_kernel_domain */ 1094 if (domain == &tomoyo_kernel_domain) 1095 continue; 1096 if (domain->is_deleted || 1097 tomoyo_pathcmp(domain->domainname, &name)) 1098 continue; 1099 domain->is_deleted = true; 1100 break; 1101 } 1102 mutex_unlock(&tomoyo_policy_lock); 1103 return 0; 1104 } 1105 1106 /** 1107 * tomoyo_write_domain2 - Write domain policy. 1108 * 1109 * @ns: Pointer to "struct tomoyo_policy_namespace". 1110 * @list: Pointer to "struct list_head". 1111 * @data: Policy to be interpreted. 1112 * @is_delete: True if it is a delete request. 1113 * 1114 * Returns 0 on success, negative value otherwise. 1115 * 1116 * Caller holds tomoyo_read_lock(). 1117 */ 1118 static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, 1119 struct list_head *list, char *data, 1120 const bool is_delete) 1121 { 1122 struct tomoyo_acl_param param = { 1123 .ns = ns, 1124 .list = list, 1125 .data = data, 1126 .is_delete = is_delete, 1127 }; 1128 static const struct { 1129 const char *keyword; 1130 int (*write)(struct tomoyo_acl_param *param); 1131 } tomoyo_callback[5] = { 1132 { "file ", tomoyo_write_file }, 1133 { "network inet ", tomoyo_write_inet_network }, 1134 { "network unix ", tomoyo_write_unix_network }, 1135 { "misc ", tomoyo_write_misc }, 1136 { "task ", tomoyo_write_task }, 1137 }; 1138 u8 i; 1139 1140 for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) { 1141 if (!tomoyo_str_starts(¶m.data, 1142 tomoyo_callback[i].keyword)) 1143 continue; 1144 return tomoyo_callback[i].write(¶m); 1145 } 1146 return -EINVAL; 1147 } 1148 1149 /* String table for domain flags. */ 1150 const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = { 1151 [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n", 1152 [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n", 1153 }; 1154 1155 /** 1156 * tomoyo_write_domain - Write domain policy. 1157 * 1158 * @head: Pointer to "struct tomoyo_io_buffer". 1159 * 1160 * Returns 0 on success, negative value otherwise. 1161 * 1162 * Caller holds tomoyo_read_lock(). 1163 */ 1164 static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 1165 { 1166 char *data = head->write_buf; 1167 struct tomoyo_policy_namespace *ns; 1168 struct tomoyo_domain_info *domain = head->w.domain; 1169 const bool is_delete = head->w.is_delete; 1170 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1171 unsigned int idx; 1172 1173 if (*data == '<') { 1174 int ret = 0; 1175 1176 domain = NULL; 1177 if (is_delete) 1178 ret = tomoyo_delete_domain(data); 1179 else if (is_select) 1180 domain = tomoyo_find_domain(data); 1181 else 1182 domain = tomoyo_assign_domain(data, false); 1183 head->w.domain = domain; 1184 return ret; 1185 } 1186 if (!domain) 1187 return -EINVAL; 1188 ns = domain->ns; 1189 if (sscanf(data, "use_profile %u", &idx) == 1 1190 && idx < TOMOYO_MAX_PROFILES) { 1191 if (!tomoyo_policy_loaded || ns->profile_ptr[idx]) 1192 if (!is_delete) 1193 domain->profile = (u8) idx; 1194 return 0; 1195 } 1196 if (sscanf(data, "use_group %u\n", &idx) == 1 1197 && idx < TOMOYO_MAX_ACL_GROUPS) { 1198 if (!is_delete) 1199 set_bit(idx, domain->group); 1200 else 1201 clear_bit(idx, domain->group); 1202 return 0; 1203 } 1204 for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) { 1205 const char *cp = tomoyo_dif[idx]; 1206 1207 if (strncmp(data, cp, strlen(cp) - 1)) 1208 continue; 1209 domain->flags[idx] = !is_delete; 1210 return 0; 1211 } 1212 return tomoyo_write_domain2(ns, &domain->acl_info_list, data, 1213 is_delete); 1214 } 1215 1216 /** 1217 * tomoyo_print_condition - Print condition part. 1218 * 1219 * @head: Pointer to "struct tomoyo_io_buffer". 1220 * @cond: Pointer to "struct tomoyo_condition". 1221 * 1222 * Returns true on success, false otherwise. 1223 */ 1224 static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, 1225 const struct tomoyo_condition *cond) 1226 { 1227 switch (head->r.cond_step) { 1228 case 0: 1229 head->r.cond_index = 0; 1230 head->r.cond_step++; 1231 if (cond->transit) { 1232 tomoyo_set_space(head); 1233 tomoyo_set_string(head, cond->transit->name); 1234 } 1235 fallthrough; 1236 case 1: 1237 { 1238 const u16 condc = cond->condc; 1239 const struct tomoyo_condition_element *condp = 1240 (typeof(condp)) (cond + 1); 1241 const struct tomoyo_number_union *numbers_p = 1242 (typeof(numbers_p)) (condp + condc); 1243 const struct tomoyo_name_union *names_p = 1244 (typeof(names_p)) 1245 (numbers_p + cond->numbers_count); 1246 const struct tomoyo_argv *argv = 1247 (typeof(argv)) (names_p + cond->names_count); 1248 const struct tomoyo_envp *envp = 1249 (typeof(envp)) (argv + cond->argc); 1250 u16 skip; 1251 1252 for (skip = 0; skip < head->r.cond_index; skip++) { 1253 const u8 left = condp->left; 1254 const u8 right = condp->right; 1255 1256 condp++; 1257 switch (left) { 1258 case TOMOYO_ARGV_ENTRY: 1259 argv++; 1260 continue; 1261 case TOMOYO_ENVP_ENTRY: 1262 envp++; 1263 continue; 1264 case TOMOYO_NUMBER_UNION: 1265 numbers_p++; 1266 break; 1267 } 1268 switch (right) { 1269 case TOMOYO_NAME_UNION: 1270 names_p++; 1271 break; 1272 case TOMOYO_NUMBER_UNION: 1273 numbers_p++; 1274 break; 1275 } 1276 } 1277 while (head->r.cond_index < condc) { 1278 const u8 match = condp->equals; 1279 const u8 left = condp->left; 1280 const u8 right = condp->right; 1281 1282 if (!tomoyo_flush(head)) 1283 return false; 1284 condp++; 1285 head->r.cond_index++; 1286 tomoyo_set_space(head); 1287 switch (left) { 1288 case TOMOYO_ARGV_ENTRY: 1289 tomoyo_io_printf(head, 1290 "exec.argv[%lu]%s=\"", 1291 argv->index, argv->is_not ? "!" : ""); 1292 tomoyo_set_string(head, 1293 argv->value->name); 1294 tomoyo_set_string(head, "\""); 1295 argv++; 1296 continue; 1297 case TOMOYO_ENVP_ENTRY: 1298 tomoyo_set_string(head, 1299 "exec.envp[\""); 1300 tomoyo_set_string(head, 1301 envp->name->name); 1302 tomoyo_io_printf(head, "\"]%s=", envp->is_not ? "!" : ""); 1303 if (envp->value) { 1304 tomoyo_set_string(head, "\""); 1305 tomoyo_set_string(head, envp->value->name); 1306 tomoyo_set_string(head, "\""); 1307 } else { 1308 tomoyo_set_string(head, 1309 "NULL"); 1310 } 1311 envp++; 1312 continue; 1313 case TOMOYO_NUMBER_UNION: 1314 tomoyo_print_number_union_nospace 1315 (head, numbers_p++); 1316 break; 1317 default: 1318 tomoyo_set_string(head, 1319 tomoyo_condition_keyword[left]); 1320 break; 1321 } 1322 tomoyo_set_string(head, match ? "=" : "!="); 1323 switch (right) { 1324 case TOMOYO_NAME_UNION: 1325 tomoyo_print_name_union_quoted 1326 (head, names_p++); 1327 break; 1328 case TOMOYO_NUMBER_UNION: 1329 tomoyo_print_number_union_nospace 1330 (head, numbers_p++); 1331 break; 1332 default: 1333 tomoyo_set_string(head, 1334 tomoyo_condition_keyword[right]); 1335 break; 1336 } 1337 } 1338 } 1339 head->r.cond_step++; 1340 fallthrough; 1341 case 2: 1342 if (!tomoyo_flush(head)) 1343 break; 1344 head->r.cond_step++; 1345 fallthrough; 1346 case 3: 1347 if (cond->grant_log != TOMOYO_GRANTLOG_AUTO) 1348 tomoyo_io_printf(head, " grant_log=%s", 1349 str_yes_no(cond->grant_log == 1350 TOMOYO_GRANTLOG_YES)); 1351 tomoyo_set_lf(head); 1352 return true; 1353 } 1354 return false; 1355 } 1356 1357 /** 1358 * tomoyo_set_group - Print "acl_group " header keyword and category name. 1359 * 1360 * @head: Pointer to "struct tomoyo_io_buffer". 1361 * @category: Category name. 1362 * 1363 * Returns nothing. 1364 */ 1365 static void tomoyo_set_group(struct tomoyo_io_buffer *head, 1366 const char *category) 1367 { 1368 if (head->type == TOMOYO_EXCEPTIONPOLICY) { 1369 tomoyo_print_namespace(head); 1370 tomoyo_io_printf(head, "acl_group %u ", 1371 head->r.acl_group_index); 1372 } 1373 tomoyo_set_string(head, category); 1374 } 1375 1376 /** 1377 * tomoyo_print_entry - Print an ACL entry. 1378 * 1379 * @head: Pointer to "struct tomoyo_io_buffer". 1380 * @acl: Pointer to an ACL entry. 1381 * 1382 * Returns true on success, false otherwise. 1383 */ 1384 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1385 struct tomoyo_acl_info *acl) 1386 { 1387 const u8 acl_type = acl->type; 1388 bool first = true; 1389 u8 bit; 1390 1391 if (head->r.print_cond_part) 1392 goto print_cond_part; 1393 if (acl->is_deleted) 1394 return true; 1395 if (!tomoyo_flush(head)) 1396 return false; 1397 else if (acl_type == TOMOYO_TYPE_PATH_ACL) { 1398 struct tomoyo_path_acl *ptr = 1399 container_of(acl, typeof(*ptr), head); 1400 const u16 perm = ptr->perm; 1401 1402 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 1403 if (!(perm & (1 << bit))) 1404 continue; 1405 if (head->r.print_transition_related_only && 1406 bit != TOMOYO_TYPE_EXECUTE) 1407 continue; 1408 if (first) { 1409 tomoyo_set_group(head, "file "); 1410 first = false; 1411 } else { 1412 tomoyo_set_slash(head); 1413 } 1414 tomoyo_set_string(head, tomoyo_path_keyword[bit]); 1415 } 1416 if (first) 1417 return true; 1418 tomoyo_print_name_union(head, &ptr->name); 1419 } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) { 1420 struct tomoyo_task_acl *ptr = 1421 container_of(acl, typeof(*ptr), head); 1422 1423 tomoyo_set_group(head, "task "); 1424 tomoyo_set_string(head, "manual_domain_transition "); 1425 tomoyo_set_string(head, ptr->domainname->name); 1426 } else if (head->r.print_transition_related_only) { 1427 return true; 1428 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1429 struct tomoyo_path2_acl *ptr = 1430 container_of(acl, typeof(*ptr), head); 1431 const u8 perm = ptr->perm; 1432 1433 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { 1434 if (!(perm & (1 << bit))) 1435 continue; 1436 if (first) { 1437 tomoyo_set_group(head, "file "); 1438 first = false; 1439 } else { 1440 tomoyo_set_slash(head); 1441 } 1442 tomoyo_set_string(head, tomoyo_mac_keywords 1443 [tomoyo_pp2mac[bit]]); 1444 } 1445 if (first) 1446 return true; 1447 tomoyo_print_name_union(head, &ptr->name1); 1448 tomoyo_print_name_union(head, &ptr->name2); 1449 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { 1450 struct tomoyo_path_number_acl *ptr = 1451 container_of(acl, typeof(*ptr), head); 1452 const u8 perm = ptr->perm; 1453 1454 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) { 1455 if (!(perm & (1 << bit))) 1456 continue; 1457 if (first) { 1458 tomoyo_set_group(head, "file "); 1459 first = false; 1460 } else { 1461 tomoyo_set_slash(head); 1462 } 1463 tomoyo_set_string(head, tomoyo_mac_keywords 1464 [tomoyo_pn2mac[bit]]); 1465 } 1466 if (first) 1467 return true; 1468 tomoyo_print_name_union(head, &ptr->name); 1469 tomoyo_print_number_union(head, &ptr->number); 1470 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { 1471 struct tomoyo_mkdev_acl *ptr = 1472 container_of(acl, typeof(*ptr), head); 1473 const u8 perm = ptr->perm; 1474 1475 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) { 1476 if (!(perm & (1 << bit))) 1477 continue; 1478 if (first) { 1479 tomoyo_set_group(head, "file "); 1480 first = false; 1481 } else { 1482 tomoyo_set_slash(head); 1483 } 1484 tomoyo_set_string(head, tomoyo_mac_keywords 1485 [tomoyo_pnnn2mac[bit]]); 1486 } 1487 if (first) 1488 return true; 1489 tomoyo_print_name_union(head, &ptr->name); 1490 tomoyo_print_number_union(head, &ptr->mode); 1491 tomoyo_print_number_union(head, &ptr->major); 1492 tomoyo_print_number_union(head, &ptr->minor); 1493 } else if (acl_type == TOMOYO_TYPE_INET_ACL) { 1494 struct tomoyo_inet_acl *ptr = 1495 container_of(acl, typeof(*ptr), head); 1496 const u8 perm = ptr->perm; 1497 1498 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { 1499 if (!(perm & (1 << bit))) 1500 continue; 1501 if (first) { 1502 tomoyo_set_group(head, "network inet "); 1503 tomoyo_set_string(head, tomoyo_proto_keyword 1504 [ptr->protocol]); 1505 tomoyo_set_space(head); 1506 first = false; 1507 } else { 1508 tomoyo_set_slash(head); 1509 } 1510 tomoyo_set_string(head, tomoyo_socket_keyword[bit]); 1511 } 1512 if (first) 1513 return true; 1514 tomoyo_set_space(head); 1515 if (ptr->address.group) { 1516 tomoyo_set_string(head, "@"); 1517 tomoyo_set_string(head, ptr->address.group->group_name 1518 ->name); 1519 } else { 1520 char buf[128]; 1521 1522 tomoyo_print_ip(buf, sizeof(buf), &ptr->address); 1523 tomoyo_io_printf(head, "%s", buf); 1524 } 1525 tomoyo_print_number_union(head, &ptr->port); 1526 } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) { 1527 struct tomoyo_unix_acl *ptr = 1528 container_of(acl, typeof(*ptr), head); 1529 const u8 perm = ptr->perm; 1530 1531 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) { 1532 if (!(perm & (1 << bit))) 1533 continue; 1534 if (first) { 1535 tomoyo_set_group(head, "network unix "); 1536 tomoyo_set_string(head, tomoyo_proto_keyword 1537 [ptr->protocol]); 1538 tomoyo_set_space(head); 1539 first = false; 1540 } else { 1541 tomoyo_set_slash(head); 1542 } 1543 tomoyo_set_string(head, tomoyo_socket_keyword[bit]); 1544 } 1545 if (first) 1546 return true; 1547 tomoyo_print_name_union(head, &ptr->name); 1548 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 1549 struct tomoyo_mount_acl *ptr = 1550 container_of(acl, typeof(*ptr), head); 1551 1552 tomoyo_set_group(head, "file mount"); 1553 tomoyo_print_name_union(head, &ptr->dev_name); 1554 tomoyo_print_name_union(head, &ptr->dir_name); 1555 tomoyo_print_name_union(head, &ptr->fs_type); 1556 tomoyo_print_number_union(head, &ptr->flags); 1557 } else if (acl_type == TOMOYO_TYPE_ENV_ACL) { 1558 struct tomoyo_env_acl *ptr = 1559 container_of(acl, typeof(*ptr), head); 1560 1561 tomoyo_set_group(head, "misc env "); 1562 tomoyo_set_string(head, ptr->env->name); 1563 } 1564 if (acl->cond) { 1565 head->r.print_cond_part = true; 1566 head->r.cond_step = 0; 1567 if (!tomoyo_flush(head)) 1568 return false; 1569 print_cond_part: 1570 if (!tomoyo_print_condition(head, acl->cond)) 1571 return false; 1572 head->r.print_cond_part = false; 1573 } else { 1574 tomoyo_set_lf(head); 1575 } 1576 return true; 1577 } 1578 1579 /** 1580 * tomoyo_read_domain2 - Read domain policy. 1581 * 1582 * @head: Pointer to "struct tomoyo_io_buffer". 1583 * @list: Pointer to "struct list_head". 1584 * 1585 * Caller holds tomoyo_read_lock(). 1586 * 1587 * Returns true on success, false otherwise. 1588 */ 1589 static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, 1590 struct list_head *list) 1591 { 1592 list_for_each_cookie(head->r.acl, list) { 1593 struct tomoyo_acl_info *ptr = 1594 list_entry(head->r.acl, typeof(*ptr), list); 1595 1596 if (!tomoyo_print_entry(head, ptr)) 1597 return false; 1598 } 1599 head->r.acl = NULL; 1600 return true; 1601 } 1602 1603 /** 1604 * tomoyo_read_domain - Read domain policy. 1605 * 1606 * @head: Pointer to "struct tomoyo_io_buffer". 1607 * 1608 * Caller holds tomoyo_read_lock(). 1609 */ 1610 static void tomoyo_read_domain(struct tomoyo_io_buffer *head) 1611 { 1612 if (head->r.eof) 1613 return; 1614 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) { 1615 struct tomoyo_domain_info *domain = 1616 list_entry(head->r.domain, typeof(*domain), list); 1617 u8 i; 1618 1619 switch (head->r.step) { 1620 case 0: 1621 if (domain->is_deleted && 1622 !head->r.print_this_domain_only) 1623 continue; 1624 /* Print domainname and flags. */ 1625 tomoyo_set_string(head, domain->domainname->name); 1626 tomoyo_set_lf(head); 1627 tomoyo_io_printf(head, "use_profile %u\n", 1628 domain->profile); 1629 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) 1630 if (domain->flags[i]) 1631 tomoyo_set_string(head, tomoyo_dif[i]); 1632 head->r.index = 0; 1633 head->r.step++; 1634 fallthrough; 1635 case 1: 1636 while (head->r.index < TOMOYO_MAX_ACL_GROUPS) { 1637 i = head->r.index++; 1638 if (!test_bit(i, domain->group)) 1639 continue; 1640 tomoyo_io_printf(head, "use_group %u\n", i); 1641 if (!tomoyo_flush(head)) 1642 return; 1643 } 1644 head->r.index = 0; 1645 head->r.step++; 1646 tomoyo_set_lf(head); 1647 fallthrough; 1648 case 2: 1649 if (!tomoyo_read_domain2(head, &domain->acl_info_list)) 1650 return; 1651 head->r.step++; 1652 if (!tomoyo_set_lf(head)) 1653 return; 1654 fallthrough; 1655 case 3: 1656 head->r.step = 0; 1657 if (head->r.print_this_domain_only) 1658 goto done; 1659 } 1660 } 1661 done: 1662 head->r.eof = true; 1663 } 1664 1665 /** 1666 * tomoyo_write_pid: Specify PID to obtain domainname. 1667 * 1668 * @head: Pointer to "struct tomoyo_io_buffer". 1669 * 1670 * Returns 0. 1671 */ 1672 static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1673 { 1674 head->r.eof = false; 1675 return 0; 1676 } 1677 1678 /** 1679 * tomoyo_read_pid - Get domainname of the specified PID. 1680 * 1681 * @head: Pointer to "struct tomoyo_io_buffer". 1682 * 1683 * Returns the domainname which the specified PID is in on success, 1684 * empty string otherwise. 1685 * The PID is specified by tomoyo_write_pid() so that the user can obtain 1686 * using read()/write() interface rather than sysctl() interface. 1687 */ 1688 static void tomoyo_read_pid(struct tomoyo_io_buffer *head) 1689 { 1690 char *buf = head->write_buf; 1691 bool global_pid = false; 1692 unsigned int pid; 1693 struct task_struct *p; 1694 struct tomoyo_domain_info *domain = NULL; 1695 1696 /* Accessing write_buf is safe because head->io_sem is held. */ 1697 if (!buf) { 1698 head->r.eof = true; 1699 return; /* Do nothing if open(O_RDONLY). */ 1700 } 1701 if (head->r.w_pos || head->r.eof) 1702 return; 1703 head->r.eof = true; 1704 if (tomoyo_str_starts(&buf, "global-pid ")) 1705 global_pid = true; 1706 if (kstrtouint(buf, 10, &pid)) 1707 return; 1708 rcu_read_lock(); 1709 if (global_pid) 1710 p = find_task_by_pid_ns(pid, &init_pid_ns); 1711 else 1712 p = find_task_by_vpid(pid); 1713 if (p) 1714 domain = tomoyo_task(p)->domain_info; 1715 rcu_read_unlock(); 1716 if (!domain) 1717 return; 1718 tomoyo_io_printf(head, "%u %u ", pid, domain->profile); 1719 tomoyo_set_string(head, domain->domainname->name); 1720 } 1721 1722 /* String table for domain transition control keywords. */ 1723 static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1724 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ", 1725 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ", 1726 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ", 1727 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ", 1728 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ", 1729 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ", 1730 }; 1731 1732 /* String table for grouping keywords. */ 1733 static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1734 [TOMOYO_PATH_GROUP] = "path_group ", 1735 [TOMOYO_NUMBER_GROUP] = "number_group ", 1736 [TOMOYO_ADDRESS_GROUP] = "address_group ", 1737 }; 1738 1739 /** 1740 * tomoyo_write_exception - Write exception policy. 1741 * 1742 * @head: Pointer to "struct tomoyo_io_buffer". 1743 * 1744 * Returns 0 on success, negative value otherwise. 1745 * 1746 * Caller holds tomoyo_read_lock(). 1747 */ 1748 static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1749 { 1750 const bool is_delete = head->w.is_delete; 1751 struct tomoyo_acl_param param = { 1752 .ns = head->w.ns, 1753 .is_delete = is_delete, 1754 .data = head->write_buf, 1755 }; 1756 u8 i; 1757 1758 if (tomoyo_str_starts(¶m.data, "aggregator ")) 1759 return tomoyo_write_aggregator(¶m); 1760 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1761 if (tomoyo_str_starts(¶m.data, tomoyo_transition_type[i])) 1762 return tomoyo_write_transition_control(¶m, i); 1763 for (i = 0; i < TOMOYO_MAX_GROUP; i++) 1764 if (tomoyo_str_starts(¶m.data, tomoyo_group_name[i])) 1765 return tomoyo_write_group(¶m, i); 1766 if (tomoyo_str_starts(¶m.data, "acl_group ")) { 1767 unsigned int group; 1768 char *data; 1769 1770 group = simple_strtoul(param.data, &data, 10); 1771 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') 1772 return tomoyo_write_domain2 1773 (head->w.ns, &head->w.ns->acl_group[group], 1774 data, is_delete); 1775 } 1776 return -EINVAL; 1777 } 1778 1779 /** 1780 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list. 1781 * 1782 * @head: Pointer to "struct tomoyo_io_buffer". 1783 * @idx: Index number. 1784 * 1785 * Returns true on success, false otherwise. 1786 * 1787 * Caller holds tomoyo_read_lock(). 1788 */ 1789 static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1790 { 1791 struct tomoyo_policy_namespace *ns = 1792 container_of(head->r.ns, typeof(*ns), namespace_list); 1793 struct list_head *list = &ns->group_list[idx]; 1794 1795 list_for_each_cookie(head->r.group, list) { 1796 struct tomoyo_group *group = 1797 list_entry(head->r.group, typeof(*group), head.list); 1798 1799 list_for_each_cookie(head->r.acl, &group->member_list) { 1800 struct tomoyo_acl_head *ptr = 1801 list_entry(head->r.acl, typeof(*ptr), list); 1802 1803 if (ptr->is_deleted) 1804 continue; 1805 if (!tomoyo_flush(head)) 1806 return false; 1807 tomoyo_print_namespace(head); 1808 tomoyo_set_string(head, tomoyo_group_name[idx]); 1809 tomoyo_set_string(head, group->group_name->name); 1810 if (idx == TOMOYO_PATH_GROUP) { 1811 tomoyo_set_space(head); 1812 tomoyo_set_string(head, container_of 1813 (ptr, struct tomoyo_path_group, 1814 head)->member_name->name); 1815 } else if (idx == TOMOYO_NUMBER_GROUP) { 1816 tomoyo_print_number_union(head, &container_of 1817 (ptr, 1818 struct tomoyo_number_group, 1819 head)->number); 1820 } else if (idx == TOMOYO_ADDRESS_GROUP) { 1821 char buffer[128]; 1822 struct tomoyo_address_group *member = 1823 container_of(ptr, typeof(*member), 1824 head); 1825 1826 tomoyo_print_ip(buffer, sizeof(buffer), 1827 &member->address); 1828 tomoyo_io_printf(head, " %s", buffer); 1829 } 1830 tomoyo_set_lf(head); 1831 } 1832 head->r.acl = NULL; 1833 } 1834 head->r.group = NULL; 1835 return true; 1836 } 1837 1838 /** 1839 * tomoyo_read_policy - Read "struct tomoyo_..._entry" list. 1840 * 1841 * @head: Pointer to "struct tomoyo_io_buffer". 1842 * @idx: Index number. 1843 * 1844 * Returns true on success, false otherwise. 1845 * 1846 * Caller holds tomoyo_read_lock(). 1847 */ 1848 static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1849 { 1850 struct tomoyo_policy_namespace *ns = 1851 container_of(head->r.ns, typeof(*ns), namespace_list); 1852 struct list_head *list = &ns->policy_list[idx]; 1853 1854 list_for_each_cookie(head->r.acl, list) { 1855 struct tomoyo_acl_head *acl = 1856 container_of(head->r.acl, typeof(*acl), list); 1857 if (acl->is_deleted) 1858 continue; 1859 if (!tomoyo_flush(head)) 1860 return false; 1861 switch (idx) { 1862 case TOMOYO_ID_TRANSITION_CONTROL: 1863 { 1864 struct tomoyo_transition_control *ptr = 1865 container_of(acl, typeof(*ptr), head); 1866 1867 tomoyo_print_namespace(head); 1868 tomoyo_set_string(head, tomoyo_transition_type 1869 [ptr->type]); 1870 tomoyo_set_string(head, ptr->program ? 1871 ptr->program->name : "any"); 1872 tomoyo_set_string(head, " from "); 1873 tomoyo_set_string(head, ptr->domainname ? 1874 ptr->domainname->name : 1875 "any"); 1876 } 1877 break; 1878 case TOMOYO_ID_AGGREGATOR: 1879 { 1880 struct tomoyo_aggregator *ptr = 1881 container_of(acl, typeof(*ptr), head); 1882 1883 tomoyo_print_namespace(head); 1884 tomoyo_set_string(head, "aggregator "); 1885 tomoyo_set_string(head, 1886 ptr->original_name->name); 1887 tomoyo_set_space(head); 1888 tomoyo_set_string(head, 1889 ptr->aggregated_name->name); 1890 } 1891 break; 1892 default: 1893 continue; 1894 } 1895 tomoyo_set_lf(head); 1896 } 1897 head->r.acl = NULL; 1898 return true; 1899 } 1900 1901 /** 1902 * tomoyo_read_exception - Read exception policy. 1903 * 1904 * @head: Pointer to "struct tomoyo_io_buffer". 1905 * 1906 * Caller holds tomoyo_read_lock(). 1907 */ 1908 static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1909 { 1910 struct tomoyo_policy_namespace *ns = 1911 container_of(head->r.ns, typeof(*ns), namespace_list); 1912 1913 if (head->r.eof) 1914 return; 1915 while (head->r.step < TOMOYO_MAX_POLICY && 1916 tomoyo_read_policy(head, head->r.step)) 1917 head->r.step++; 1918 if (head->r.step < TOMOYO_MAX_POLICY) 1919 return; 1920 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP && 1921 tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY)) 1922 head->r.step++; 1923 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) 1924 return; 1925 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP 1926 + TOMOYO_MAX_ACL_GROUPS) { 1927 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY 1928 - TOMOYO_MAX_GROUP; 1929 if (!tomoyo_read_domain2(head, &ns->acl_group 1930 [head->r.acl_group_index])) 1931 return; 1932 head->r.step++; 1933 } 1934 head->r.eof = true; 1935 } 1936 1937 /* Wait queue for kernel -> userspace notification. */ 1938 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait); 1939 /* Wait queue for userspace -> kernel notification. */ 1940 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait); 1941 1942 /* Structure for query. */ 1943 struct tomoyo_query { 1944 struct list_head list; 1945 struct tomoyo_domain_info *domain; 1946 char *query; 1947 size_t query_len; 1948 unsigned int serial; 1949 u8 timer; 1950 u8 answer; 1951 u8 retry; 1952 }; 1953 1954 /* The list for "struct tomoyo_query". */ 1955 static LIST_HEAD(tomoyo_query_list); 1956 1957 /* Lock for manipulating tomoyo_query_list. */ 1958 static DEFINE_SPINLOCK(tomoyo_query_list_lock); 1959 1960 /* 1961 * Number of "struct file" referring /sys/kernel/security/tomoyo/query 1962 * interface. 1963 */ 1964 static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1965 1966 /** 1967 * tomoyo_truncate - Truncate a line. 1968 * 1969 * @str: String to truncate. 1970 * 1971 * Returns length of truncated @str. 1972 */ 1973 static int tomoyo_truncate(char *str) 1974 { 1975 char *start = str; 1976 1977 while (*(unsigned char *) str > (unsigned char) ' ') 1978 str++; 1979 *str = '\0'; 1980 return strlen(start) + 1; 1981 } 1982 1983 /** 1984 * tomoyo_numscan - sscanf() which stores the length of a decimal integer value. 1985 * 1986 * @str: String to scan. 1987 * @head: Leading string that must start with. 1988 * @width: Pointer to "int" for storing length of a decimal integer value after @head. 1989 * @tail: Optional character that must match after a decimal integer value. 1990 * 1991 * Returns whether @str starts with @head and a decimal value follows @head. 1992 */ 1993 static bool tomoyo_numscan(const char *str, const char *head, int *width, const char tail) 1994 { 1995 const char *cp; 1996 const int n = strlen(head); 1997 1998 if (!strncmp(str, head, n)) { 1999 cp = str + n; 2000 while (*cp && *cp >= '0' && *cp <= '9') 2001 cp++; 2002 if (*cp == tail || !tail) { 2003 *width = cp - (str + n); 2004 return *width != 0; 2005 } 2006 } 2007 *width = 0; 2008 return 0; 2009 } 2010 2011 /** 2012 * tomoyo_patternize_path - Make patterns for file path. Used by learning mode. 2013 * 2014 * @buffer: Destination buffer. 2015 * @len: Size of @buffer. 2016 * @entry: Original line. 2017 * 2018 * Returns nothing. 2019 */ 2020 static void tomoyo_patternize_path(char *buffer, const int len, char *entry) 2021 { 2022 int width; 2023 char *cp = entry; 2024 2025 /* Nothing to do if this line is not for "file" related entry. */ 2026 if (strncmp(entry, "file ", 5)) 2027 goto flush; 2028 /* 2029 * Nothing to do if there is no colon in this line, for this rewriting 2030 * applies to only filesystems where numeric values in the path are volatile. 2031 */ 2032 cp = strchr(entry + 5, ':'); 2033 if (!cp) { 2034 cp = entry; 2035 goto flush; 2036 } 2037 /* Flush e.g. "file ioctl" part. */ 2038 while (*cp != ' ') 2039 cp--; 2040 *cp++ = '\0'; 2041 tomoyo_addprintf(buffer, len, "%s ", entry); 2042 /* e.g. file ioctl pipe:[$INO] $CMD */ 2043 if (tomoyo_numscan(cp, "pipe:[", &width, ']')) { 2044 cp += width + 7; 2045 tomoyo_addprintf(buffer, len, "pipe:[\\$]"); 2046 goto flush; 2047 } 2048 /* e.g. file ioctl socket:[$INO] $CMD */ 2049 if (tomoyo_numscan(cp, "socket:[", &width, ']')) { 2050 cp += width + 9; 2051 tomoyo_addprintf(buffer, len, "socket:[\\$]"); 2052 goto flush; 2053 } 2054 if (!strncmp(cp, "proc:/self", 10)) { 2055 /* e.g. file read proc:/self/task/$TID/fdinfo/$FD */ 2056 cp += 10; 2057 tomoyo_addprintf(buffer, len, "proc:/self"); 2058 } else if (tomoyo_numscan(cp, "proc:/", &width, 0)) { 2059 /* e.g. file read proc:/$PID/task/$TID/fdinfo/$FD */ 2060 /* 2061 * Don't patternize $PID part if $PID == 1, for several 2062 * programs access only files in /proc/1/ directory. 2063 */ 2064 cp += width + 6; 2065 if (width == 1 && *(cp - 1) == '1') 2066 tomoyo_addprintf(buffer, len, "proc:/1"); 2067 else 2068 tomoyo_addprintf(buffer, len, "proc:/\\$"); 2069 } else { 2070 goto flush; 2071 } 2072 /* Patternize $TID part if "/task/" follows. */ 2073 if (tomoyo_numscan(cp, "/task/", &width, 0)) { 2074 cp += width + 6; 2075 tomoyo_addprintf(buffer, len, "/task/\\$"); 2076 } 2077 /* Patternize $FD part if "/fd/" or "/fdinfo/" follows. */ 2078 if (tomoyo_numscan(cp, "/fd/", &width, 0)) { 2079 cp += width + 4; 2080 tomoyo_addprintf(buffer, len, "/fd/\\$"); 2081 } else if (tomoyo_numscan(cp, "/fdinfo/", &width, 0)) { 2082 cp += width + 8; 2083 tomoyo_addprintf(buffer, len, "/fdinfo/\\$"); 2084 } 2085 flush: 2086 /* Flush remaining part if any. */ 2087 if (*cp) 2088 tomoyo_addprintf(buffer, len, "%s", cp); 2089 } 2090 2091 /** 2092 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. 2093 * 2094 * @domain: Pointer to "struct tomoyo_domain_info". 2095 * @header: Lines containing ACL. 2096 * 2097 * Returns nothing. 2098 */ 2099 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) 2100 { 2101 char *buffer; 2102 char *realpath = NULL; 2103 char *argv0 = NULL; 2104 char *symlink = NULL; 2105 char *cp = strchr(header, '\n'); 2106 int len; 2107 2108 if (!cp) 2109 return; 2110 cp = strchr(cp + 1, '\n'); 2111 if (!cp) 2112 return; 2113 *cp++ = '\0'; 2114 /* Reserve some space for potentially using patterns. */ 2115 len = strlen(cp) + 16; 2116 /* strstr() will return NULL if ordering is wrong. */ 2117 if (*cp == 'f') { 2118 argv0 = strstr(header, " argv[]={ \""); 2119 if (argv0) { 2120 argv0 += 10; 2121 len += tomoyo_truncate(argv0) + 14; 2122 } 2123 realpath = strstr(header, " exec={ realpath=\""); 2124 if (realpath) { 2125 realpath += 8; 2126 len += tomoyo_truncate(realpath) + 6; 2127 } 2128 symlink = strstr(header, " symlink.target=\""); 2129 if (symlink) 2130 len += tomoyo_truncate(symlink + 1) + 1; 2131 } 2132 buffer = kmalloc(len, GFP_NOFS | __GFP_ZERO); 2133 if (!buffer) 2134 return; 2135 tomoyo_patternize_path(buffer, len, cp); 2136 if (realpath) 2137 tomoyo_addprintf(buffer, len, " exec.%s", realpath); 2138 if (argv0) 2139 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0); 2140 if (symlink) 2141 tomoyo_addprintf(buffer, len, "%s", symlink); 2142 tomoyo_normalize_line(buffer); 2143 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, 2144 false)) 2145 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 2146 kfree(buffer); 2147 } 2148 2149 /** 2150 * tomoyo_supervisor - Ask for the supervisor's decision. 2151 * 2152 * @r: Pointer to "struct tomoyo_request_info". 2153 * @fmt: The printf()'s format string, followed by parameters. 2154 * 2155 * Returns 0 if the supervisor decided to permit the access request which 2156 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the 2157 * supervisor decided to retry the access request which violated the policy in 2158 * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise. 2159 */ 2160 int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 2161 { 2162 va_list args; 2163 int error; 2164 int len; 2165 static unsigned int tomoyo_serial; 2166 struct tomoyo_query entry = { }; 2167 bool quota_exceeded = false; 2168 2169 va_start(args, fmt); 2170 len = vsnprintf(NULL, 0, fmt, args) + 1; 2171 va_end(args); 2172 /* Write /sys/kernel/security/tomoyo/audit. */ 2173 va_start(args, fmt); 2174 tomoyo_write_log2(r, len, fmt, args); 2175 va_end(args); 2176 /* Nothing more to do if granted. */ 2177 if (r->granted) 2178 return 0; 2179 if (r->mode) 2180 tomoyo_update_stat(r->mode); 2181 switch (r->mode) { 2182 case TOMOYO_CONFIG_ENFORCING: 2183 error = -EPERM; 2184 if (atomic_read(&tomoyo_query_observers)) 2185 break; 2186 goto out; 2187 case TOMOYO_CONFIG_LEARNING: 2188 error = 0; 2189 /* Check max_learning_entry parameter. */ 2190 if (tomoyo_domain_quota_is_ok(r)) 2191 break; 2192 fallthrough; 2193 default: 2194 return 0; 2195 } 2196 /* Get message. */ 2197 va_start(args, fmt); 2198 entry.query = tomoyo_init_log(r, len, fmt, args); 2199 va_end(args); 2200 if (!entry.query) 2201 goto out; 2202 entry.query_len = strlen(entry.query) + 1; 2203 if (!error) { 2204 tomoyo_add_entry(r->domain, entry.query); 2205 goto out; 2206 } 2207 len = kmalloc_size_roundup(entry.query_len); 2208 entry.domain = r->domain; 2209 spin_lock(&tomoyo_query_list_lock); 2210 if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] && 2211 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len 2212 >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) { 2213 quota_exceeded = true; 2214 } else { 2215 entry.serial = tomoyo_serial++; 2216 entry.retry = r->retry; 2217 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len; 2218 list_add_tail(&entry.list, &tomoyo_query_list); 2219 } 2220 spin_unlock(&tomoyo_query_list_lock); 2221 if (quota_exceeded) 2222 goto out; 2223 /* Give 10 seconds for supervisor's opinion. */ 2224 while (entry.timer < 10) { 2225 wake_up_all(&tomoyo_query_wait); 2226 if (wait_event_interruptible_timeout 2227 (tomoyo_answer_wait, entry.answer || 2228 !atomic_read(&tomoyo_query_observers), HZ)) 2229 break; 2230 entry.timer++; 2231 } 2232 spin_lock(&tomoyo_query_list_lock); 2233 list_del(&entry.list); 2234 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len; 2235 spin_unlock(&tomoyo_query_list_lock); 2236 switch (entry.answer) { 2237 case 3: /* Asked to retry by administrator. */ 2238 error = TOMOYO_RETRY_REQUEST; 2239 r->retry++; 2240 break; 2241 case 1: 2242 /* Granted by administrator. */ 2243 error = 0; 2244 break; 2245 default: 2246 /* Timed out or rejected by administrator. */ 2247 break; 2248 } 2249 out: 2250 kfree(entry.query); 2251 return error; 2252 } 2253 2254 /** 2255 * tomoyo_find_domain_by_qid - Get domain by query id. 2256 * 2257 * @serial: Query ID assigned by tomoyo_supervisor(). 2258 * 2259 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. 2260 */ 2261 static struct tomoyo_domain_info *tomoyo_find_domain_by_qid 2262 (unsigned int serial) 2263 { 2264 struct tomoyo_query *ptr; 2265 struct tomoyo_domain_info *domain = NULL; 2266 2267 spin_lock(&tomoyo_query_list_lock); 2268 list_for_each_entry(ptr, &tomoyo_query_list, list) { 2269 if (ptr->serial != serial) 2270 continue; 2271 domain = ptr->domain; 2272 break; 2273 } 2274 spin_unlock(&tomoyo_query_list_lock); 2275 return domain; 2276 } 2277 2278 /** 2279 * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query. 2280 * 2281 * @file: Pointer to "struct file". 2282 * @wait: Pointer to "poll_table". 2283 * 2284 * Returns EPOLLIN | EPOLLRDNORM when ready to read, 0 otherwise. 2285 * 2286 * Waits for access requests which violated policy in enforcing mode. 2287 */ 2288 static __poll_t tomoyo_poll_query(struct file *file, poll_table *wait) 2289 { 2290 if (!list_empty(&tomoyo_query_list)) 2291 return EPOLLIN | EPOLLRDNORM; 2292 poll_wait(file, &tomoyo_query_wait, wait); 2293 if (!list_empty(&tomoyo_query_list)) 2294 return EPOLLIN | EPOLLRDNORM; 2295 return 0; 2296 } 2297 2298 /** 2299 * tomoyo_read_query - Read access requests which violated policy in enforcing mode. 2300 * 2301 * @head: Pointer to "struct tomoyo_io_buffer". 2302 */ 2303 static void tomoyo_read_query(struct tomoyo_io_buffer *head) 2304 { 2305 struct list_head *tmp; 2306 unsigned int pos = 0; 2307 size_t len = 0; 2308 char *buf; 2309 2310 if (head->r.w_pos) 2311 return; 2312 kfree(head->read_buf); 2313 head->read_buf = NULL; 2314 spin_lock(&tomoyo_query_list_lock); 2315 list_for_each(tmp, &tomoyo_query_list) { 2316 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2317 2318 if (pos++ != head->r.query_index) 2319 continue; 2320 len = ptr->query_len; 2321 break; 2322 } 2323 spin_unlock(&tomoyo_query_list_lock); 2324 if (!len) { 2325 head->r.query_index = 0; 2326 return; 2327 } 2328 buf = kzalloc(len + 32, GFP_NOFS); 2329 if (!buf) 2330 return; 2331 pos = 0; 2332 spin_lock(&tomoyo_query_list_lock); 2333 list_for_each(tmp, &tomoyo_query_list) { 2334 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2335 2336 if (pos++ != head->r.query_index) 2337 continue; 2338 /* 2339 * Some query can be skipped because tomoyo_query_list 2340 * can change, but I don't care. 2341 */ 2342 if (len == ptr->query_len) 2343 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial, 2344 ptr->retry, ptr->query); 2345 break; 2346 } 2347 spin_unlock(&tomoyo_query_list_lock); 2348 if (buf[0]) { 2349 head->read_buf = buf; 2350 head->r.w[head->r.w_pos++] = buf; 2351 head->r.query_index++; 2352 } else { 2353 kfree(buf); 2354 } 2355 } 2356 2357 /** 2358 * tomoyo_write_answer - Write the supervisor's decision. 2359 * 2360 * @head: Pointer to "struct tomoyo_io_buffer". 2361 * 2362 * Returns 0 on success, -EINVAL otherwise. 2363 */ 2364 static int tomoyo_write_answer(struct tomoyo_io_buffer *head) 2365 { 2366 char *data = head->write_buf; 2367 struct list_head *tmp; 2368 unsigned int serial; 2369 unsigned int answer; 2370 2371 spin_lock(&tomoyo_query_list_lock); 2372 list_for_each(tmp, &tomoyo_query_list) { 2373 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2374 2375 ptr->timer = 0; 2376 } 2377 spin_unlock(&tomoyo_query_list_lock); 2378 if (sscanf(data, "A%u=%u", &serial, &answer) != 2) 2379 return -EINVAL; 2380 spin_lock(&tomoyo_query_list_lock); 2381 list_for_each(tmp, &tomoyo_query_list) { 2382 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2383 2384 if (ptr->serial != serial) 2385 continue; 2386 ptr->answer = answer; 2387 /* Remove from tomoyo_query_list. */ 2388 if (ptr->answer) 2389 list_del_init(&ptr->list); 2390 break; 2391 } 2392 spin_unlock(&tomoyo_query_list_lock); 2393 return 0; 2394 } 2395 2396 /** 2397 * tomoyo_read_version: Get version. 2398 * 2399 * @head: Pointer to "struct tomoyo_io_buffer". 2400 * 2401 * Returns version information. 2402 */ 2403 static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2404 { 2405 if (!head->r.eof) { 2406 tomoyo_io_printf(head, "2.6.0"); 2407 head->r.eof = true; 2408 } 2409 } 2410 2411 /* String table for /sys/kernel/security/tomoyo/stat interface. */ 2412 static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = { 2413 [TOMOYO_STAT_POLICY_UPDATES] = "update:", 2414 [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:", 2415 [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:", 2416 [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:", 2417 }; 2418 2419 /* String table for /sys/kernel/security/tomoyo/stat interface. */ 2420 static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = { 2421 [TOMOYO_MEMORY_POLICY] = "policy:", 2422 [TOMOYO_MEMORY_AUDIT] = "audit log:", 2423 [TOMOYO_MEMORY_QUERY] = "query message:", 2424 }; 2425 2426 /* Counter for number of updates. */ 2427 static atomic_t tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT]; 2428 /* Timestamp counter for last updated. */ 2429 static time64_t tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT]; 2430 2431 /** 2432 * tomoyo_update_stat - Update statistic counters. 2433 * 2434 * @index: Index for policy type. 2435 * 2436 * Returns nothing. 2437 */ 2438 void tomoyo_update_stat(const u8 index) 2439 { 2440 atomic_inc(&tomoyo_stat_updated[index]); 2441 tomoyo_stat_modified[index] = ktime_get_real_seconds(); 2442 } 2443 2444 /** 2445 * tomoyo_read_stat - Read statistic data. 2446 * 2447 * @head: Pointer to "struct tomoyo_io_buffer". 2448 * 2449 * Returns nothing. 2450 */ 2451 static void tomoyo_read_stat(struct tomoyo_io_buffer *head) 2452 { 2453 u8 i; 2454 unsigned int total = 0; 2455 2456 if (head->r.eof) 2457 return; 2458 for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) { 2459 tomoyo_io_printf(head, "Policy %-30s %10u", 2460 tomoyo_policy_headers[i], 2461 atomic_read(&tomoyo_stat_updated[i])); 2462 if (tomoyo_stat_modified[i]) { 2463 struct tomoyo_time stamp; 2464 2465 tomoyo_convert_time(tomoyo_stat_modified[i], &stamp); 2466 tomoyo_io_printf(head, " (Last: %04u/%02u/%02u %02u:%02u:%02u)", 2467 stamp.year, stamp.month, stamp.day, 2468 stamp.hour, stamp.min, stamp.sec); 2469 } 2470 tomoyo_set_lf(head); 2471 } 2472 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) { 2473 unsigned int used = tomoyo_memory_used[i]; 2474 2475 total += used; 2476 tomoyo_io_printf(head, "Memory used by %-22s %10u", 2477 tomoyo_memory_headers[i], used); 2478 used = tomoyo_memory_quota[i]; 2479 if (used) 2480 tomoyo_io_printf(head, " (Quota: %10u)", used); 2481 tomoyo_set_lf(head); 2482 } 2483 tomoyo_io_printf(head, "Total memory used: %10u\n", 2484 total); 2485 head->r.eof = true; 2486 } 2487 2488 /** 2489 * tomoyo_write_stat - Set memory quota. 2490 * 2491 * @head: Pointer to "struct tomoyo_io_buffer". 2492 * 2493 * Returns 0. 2494 */ 2495 static int tomoyo_write_stat(struct tomoyo_io_buffer *head) 2496 { 2497 char *data = head->write_buf; 2498 u8 i; 2499 2500 if (tomoyo_str_starts(&data, "Memory used by ")) 2501 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) 2502 if (tomoyo_str_starts(&data, tomoyo_memory_headers[i])) 2503 sscanf(data, "%u", &tomoyo_memory_quota[i]); 2504 return 0; 2505 } 2506 2507 /** 2508 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 2509 * 2510 * @type: Type of interface. 2511 * @file: Pointer to "struct file". 2512 * 2513 * Returns 0 on success, negative value otherwise. 2514 */ 2515 int tomoyo_open_control(const u8 type, struct file *file) 2516 { 2517 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS); 2518 2519 if (!head) 2520 return -ENOMEM; 2521 mutex_init(&head->io_sem); 2522 head->type = type; 2523 switch (type) { 2524 case TOMOYO_DOMAINPOLICY: 2525 /* /sys/kernel/security/tomoyo/domain_policy */ 2526 head->write = tomoyo_write_domain; 2527 head->read = tomoyo_read_domain; 2528 break; 2529 case TOMOYO_EXCEPTIONPOLICY: 2530 /* /sys/kernel/security/tomoyo/exception_policy */ 2531 head->write = tomoyo_write_exception; 2532 head->read = tomoyo_read_exception; 2533 break; 2534 case TOMOYO_AUDIT: 2535 /* /sys/kernel/security/tomoyo/audit */ 2536 head->poll = tomoyo_poll_log; 2537 head->read = tomoyo_read_log; 2538 break; 2539 case TOMOYO_PROCESS_STATUS: 2540 /* /sys/kernel/security/tomoyo/.process_status */ 2541 head->write = tomoyo_write_pid; 2542 head->read = tomoyo_read_pid; 2543 break; 2544 case TOMOYO_VERSION: 2545 /* /sys/kernel/security/tomoyo/version */ 2546 head->read = tomoyo_read_version; 2547 head->readbuf_size = 128; 2548 break; 2549 case TOMOYO_STAT: 2550 /* /sys/kernel/security/tomoyo/stat */ 2551 head->write = tomoyo_write_stat; 2552 head->read = tomoyo_read_stat; 2553 head->readbuf_size = 1024; 2554 break; 2555 case TOMOYO_PROFILE: 2556 /* /sys/kernel/security/tomoyo/profile */ 2557 head->write = tomoyo_write_profile; 2558 head->read = tomoyo_read_profile; 2559 break; 2560 case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */ 2561 head->poll = tomoyo_poll_query; 2562 head->write = tomoyo_write_answer; 2563 head->read = tomoyo_read_query; 2564 break; 2565 case TOMOYO_MANAGER: 2566 /* /sys/kernel/security/tomoyo/manager */ 2567 head->write = tomoyo_write_manager; 2568 head->read = tomoyo_read_manager; 2569 break; 2570 } 2571 if (!(file->f_mode & FMODE_READ)) { 2572 /* 2573 * No need to allocate read_buf since it is not opened 2574 * for reading. 2575 */ 2576 head->read = NULL; 2577 head->poll = NULL; 2578 } else if (!head->poll) { 2579 /* Don't allocate read_buf for poll() access. */ 2580 if (!head->readbuf_size) 2581 head->readbuf_size = 4096 * 2; 2582 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS); 2583 if (!head->read_buf) { 2584 kfree(head); 2585 return -ENOMEM; 2586 } 2587 } 2588 if (!(file->f_mode & FMODE_WRITE)) { 2589 /* 2590 * No need to allocate write_buf since it is not opened 2591 * for writing. 2592 */ 2593 head->write = NULL; 2594 } else if (head->write) { 2595 head->writebuf_size = 4096 * 2; 2596 head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS); 2597 if (!head->write_buf) { 2598 kfree(head->read_buf); 2599 kfree(head); 2600 return -ENOMEM; 2601 } 2602 } 2603 /* 2604 * If the file is /sys/kernel/security/tomoyo/query , increment the 2605 * observer counter. 2606 * The obserber counter is used by tomoyo_supervisor() to see if 2607 * there is some process monitoring /sys/kernel/security/tomoyo/query. 2608 */ 2609 if (type == TOMOYO_QUERY) 2610 atomic_inc(&tomoyo_query_observers); 2611 file->private_data = head; 2612 tomoyo_notify_gc(head, true); 2613 return 0; 2614 } 2615 2616 /** 2617 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. 2618 * 2619 * @file: Pointer to "struct file". 2620 * @wait: Pointer to "poll_table". Maybe NULL. 2621 * 2622 * Returns EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM if ready to read/write, 2623 * EPOLLOUT | EPOLLWRNORM otherwise. 2624 */ 2625 __poll_t tomoyo_poll_control(struct file *file, poll_table *wait) 2626 { 2627 struct tomoyo_io_buffer *head = file->private_data; 2628 2629 if (head->poll) 2630 return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM; 2631 return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM; 2632 } 2633 2634 /** 2635 * tomoyo_set_namespace_cursor - Set namespace to read. 2636 * 2637 * @head: Pointer to "struct tomoyo_io_buffer". 2638 * 2639 * Returns nothing. 2640 */ 2641 static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head) 2642 { 2643 struct list_head *ns; 2644 2645 if (head->type != TOMOYO_EXCEPTIONPOLICY && 2646 head->type != TOMOYO_PROFILE) 2647 return; 2648 /* 2649 * If this is the first read, or reading previous namespace finished 2650 * and has more namespaces to read, update the namespace cursor. 2651 */ 2652 ns = head->r.ns; 2653 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) { 2654 /* Clearing is OK because tomoyo_flush() returned true. */ 2655 memset(&head->r, 0, sizeof(head->r)); 2656 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next; 2657 } 2658 } 2659 2660 /** 2661 * tomoyo_has_more_namespace - Check for unread namespaces. 2662 * 2663 * @head: Pointer to "struct tomoyo_io_buffer". 2664 * 2665 * Returns true if we have more entries to print, false otherwise. 2666 */ 2667 static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head) 2668 { 2669 return (head->type == TOMOYO_EXCEPTIONPOLICY || 2670 head->type == TOMOYO_PROFILE) && head->r.eof && 2671 head->r.ns->next != &tomoyo_namespace_list; 2672 } 2673 2674 /** 2675 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2676 * 2677 * @head: Pointer to "struct tomoyo_io_buffer". 2678 * @buffer: Pointer to buffer to write to. 2679 * @buffer_len: Size of @buffer. 2680 * 2681 * Returns bytes read on success, negative value otherwise. 2682 */ 2683 ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, 2684 const int buffer_len) 2685 { 2686 int len; 2687 int idx; 2688 2689 if (!head->read) 2690 return -EINVAL; 2691 if (mutex_lock_interruptible(&head->io_sem)) 2692 return -EINTR; 2693 head->read_user_buf = buffer; 2694 head->read_user_buf_avail = buffer_len; 2695 idx = tomoyo_read_lock(); 2696 if (tomoyo_flush(head)) 2697 /* Call the policy handler. */ 2698 do { 2699 tomoyo_set_namespace_cursor(head); 2700 head->read(head); 2701 } while (tomoyo_flush(head) && 2702 tomoyo_has_more_namespace(head)); 2703 tomoyo_read_unlock(idx); 2704 len = head->read_user_buf - buffer; 2705 mutex_unlock(&head->io_sem); 2706 return len; 2707 } 2708 2709 /** 2710 * tomoyo_parse_policy - Parse a policy line. 2711 * 2712 * @head: Pointer to "struct tomoyo_io_buffer". 2713 * @line: Line to parse. 2714 * 2715 * Returns 0 on success, negative value otherwise. 2716 * 2717 * Caller holds tomoyo_read_lock(). 2718 */ 2719 static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line) 2720 { 2721 /* Delete request? */ 2722 head->w.is_delete = !strncmp(line, "delete ", 7); 2723 if (head->w.is_delete) 2724 memmove(line, line + 7, strlen(line + 7) + 1); 2725 /* Selecting namespace to update. */ 2726 if (head->type == TOMOYO_EXCEPTIONPOLICY || 2727 head->type == TOMOYO_PROFILE) { 2728 if (*line == '<') { 2729 char *cp = strchr(line, ' '); 2730 2731 if (cp) { 2732 *cp++ = '\0'; 2733 head->w.ns = tomoyo_assign_namespace(line); 2734 memmove(line, cp, strlen(cp) + 1); 2735 } else 2736 head->w.ns = NULL; 2737 } else 2738 head->w.ns = &tomoyo_kernel_namespace; 2739 /* Don't allow updating if namespace is invalid. */ 2740 if (!head->w.ns) 2741 return -ENOENT; 2742 } 2743 /* Do the update. */ 2744 return head->write(head); 2745 } 2746 2747 /** 2748 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2749 * 2750 * @head: Pointer to "struct tomoyo_io_buffer". 2751 * @buffer: Pointer to buffer to read from. 2752 * @buffer_len: Size of @buffer. 2753 * 2754 * Returns @buffer_len on success, negative value otherwise. 2755 */ 2756 ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, 2757 const char __user *buffer, const int buffer_len) 2758 { 2759 int error = buffer_len; 2760 size_t avail_len = buffer_len; 2761 char *cp0; 2762 int idx; 2763 2764 if (!head->write) 2765 return -EINVAL; 2766 if (mutex_lock_interruptible(&head->io_sem)) 2767 return -EINTR; 2768 cp0 = head->write_buf; 2769 head->read_user_buf_avail = 0; 2770 idx = tomoyo_read_lock(); 2771 /* Read a line and dispatch it to the policy handler. */ 2772 while (avail_len > 0) { 2773 char c; 2774 2775 if (head->w.avail >= head->writebuf_size - 1) { 2776 const int len = head->writebuf_size * 2; 2777 char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN); 2778 2779 if (!cp) { 2780 error = -ENOMEM; 2781 break; 2782 } 2783 memmove(cp, cp0, head->w.avail); 2784 kfree(cp0); 2785 head->write_buf = cp; 2786 cp0 = cp; 2787 head->writebuf_size = len; 2788 } 2789 if (get_user(c, buffer)) { 2790 error = -EFAULT; 2791 break; 2792 } 2793 buffer++; 2794 avail_len--; 2795 cp0[head->w.avail++] = c; 2796 if (c != '\n') 2797 continue; 2798 cp0[head->w.avail - 1] = '\0'; 2799 head->w.avail = 0; 2800 tomoyo_normalize_line(cp0); 2801 if (!strcmp(cp0, "reset")) { 2802 head->w.ns = &tomoyo_kernel_namespace; 2803 head->w.domain = NULL; 2804 memset(&head->r, 0, sizeof(head->r)); 2805 continue; 2806 } 2807 /* Don't allow updating policies by non manager programs. */ 2808 switch (head->type) { 2809 case TOMOYO_PROCESS_STATUS: 2810 /* This does not write anything. */ 2811 break; 2812 case TOMOYO_DOMAINPOLICY: 2813 if (tomoyo_select_domain(head, cp0)) 2814 continue; 2815 fallthrough; 2816 case TOMOYO_EXCEPTIONPOLICY: 2817 if (!strcmp(cp0, "select transition_only")) { 2818 head->r.print_transition_related_only = true; 2819 continue; 2820 } 2821 fallthrough; 2822 default: 2823 if (!tomoyo_manager()) { 2824 error = -EPERM; 2825 goto out; 2826 } 2827 } 2828 switch (tomoyo_parse_policy(head, cp0)) { 2829 case -EPERM: 2830 error = -EPERM; 2831 goto out; 2832 case 0: 2833 switch (head->type) { 2834 case TOMOYO_DOMAINPOLICY: 2835 case TOMOYO_EXCEPTIONPOLICY: 2836 case TOMOYO_STAT: 2837 case TOMOYO_PROFILE: 2838 case TOMOYO_MANAGER: 2839 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 2840 break; 2841 default: 2842 break; 2843 } 2844 break; 2845 } 2846 } 2847 out: 2848 tomoyo_read_unlock(idx); 2849 mutex_unlock(&head->io_sem); 2850 return error; 2851 } 2852 2853 /** 2854 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2855 * 2856 * @head: Pointer to "struct tomoyo_io_buffer". 2857 */ 2858 void tomoyo_close_control(struct tomoyo_io_buffer *head) 2859 { 2860 /* 2861 * If the file is /sys/kernel/security/tomoyo/query , decrement the 2862 * observer counter. 2863 */ 2864 if (head->type == TOMOYO_QUERY && 2865 atomic_dec_and_test(&tomoyo_query_observers)) 2866 wake_up_all(&tomoyo_answer_wait); 2867 tomoyo_notify_gc(head, false); 2868 } 2869 2870 /** 2871 * tomoyo_check_profile - Check all profiles currently assigned to domains are defined. 2872 */ 2873 void tomoyo_check_profile(void) 2874 { 2875 struct tomoyo_domain_info *domain; 2876 const int idx = tomoyo_read_lock(); 2877 2878 tomoyo_policy_loaded = true; 2879 pr_info("TOMOYO: 2.6.0\n"); 2880 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, 2881 srcu_read_lock_held(&tomoyo_ss)) { 2882 const u8 profile = domain->profile; 2883 struct tomoyo_policy_namespace *ns = domain->ns; 2884 2885 if (ns->profile_version == 20110903) { 2886 pr_info_once("Converting profile version from %u to %u.\n", 2887 20110903, 20150505); 2888 ns->profile_version = 20150505; 2889 } 2890 if (ns->profile_version != 20150505) 2891 pr_err("Profile version %u is not supported.\n", 2892 ns->profile_version); 2893 else if (!ns->profile_ptr[profile]) 2894 pr_err("Profile %u (used by '%s') is not defined.\n", 2895 profile, domain->domainname->name); 2896 else 2897 continue; 2898 pr_err("Userland tools for TOMOYO 2.6 must be installed and policy must be initialized.\n"); 2899 pr_err("Please see https://tomoyo.sourceforge.net/2.6/ for more information.\n"); 2900 panic("STOP!"); 2901 } 2902 tomoyo_read_unlock(idx); 2903 pr_info("Mandatory Access Control activated.\n"); 2904 } 2905 2906 /** 2907 * tomoyo_load_builtin_policy - Load built-in policy. 2908 * 2909 * Returns nothing. 2910 */ 2911 void __init tomoyo_load_builtin_policy(void) 2912 { 2913 #ifdef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING 2914 static char tomoyo_builtin_profile[] __initdata = 2915 "PROFILE_VERSION=20150505\n" 2916 "0-CONFIG={ mode=learning grant_log=no reject_log=yes }\n"; 2917 static char tomoyo_builtin_exception_policy[] __initdata = 2918 "aggregator proc:/self/exe /proc/self/exe\n"; 2919 static char tomoyo_builtin_domain_policy[] __initdata = ""; 2920 static char tomoyo_builtin_manager[] __initdata = ""; 2921 static char tomoyo_builtin_stat[] __initdata = ""; 2922 #else 2923 /* 2924 * This include file is manually created and contains built-in policy 2925 * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy", 2926 * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager", 2927 * "tomoyo_builtin_stat" in the form of "static char [] __initdata". 2928 */ 2929 #include "builtin-policy.h" 2930 #endif 2931 u8 i; 2932 const int idx = tomoyo_read_lock(); 2933 2934 for (i = 0; i < 5; i++) { 2935 struct tomoyo_io_buffer head = { }; 2936 char *start = ""; 2937 2938 switch (i) { 2939 case 0: 2940 start = tomoyo_builtin_profile; 2941 head.type = TOMOYO_PROFILE; 2942 head.write = tomoyo_write_profile; 2943 break; 2944 case 1: 2945 start = tomoyo_builtin_exception_policy; 2946 head.type = TOMOYO_EXCEPTIONPOLICY; 2947 head.write = tomoyo_write_exception; 2948 break; 2949 case 2: 2950 start = tomoyo_builtin_domain_policy; 2951 head.type = TOMOYO_DOMAINPOLICY; 2952 head.write = tomoyo_write_domain; 2953 break; 2954 case 3: 2955 start = tomoyo_builtin_manager; 2956 head.type = TOMOYO_MANAGER; 2957 head.write = tomoyo_write_manager; 2958 break; 2959 case 4: 2960 start = tomoyo_builtin_stat; 2961 head.type = TOMOYO_STAT; 2962 head.write = tomoyo_write_stat; 2963 break; 2964 } 2965 while (1) { 2966 char *end = strchr(start, '\n'); 2967 2968 if (!end) 2969 break; 2970 *end = '\0'; 2971 tomoyo_normalize_line(start); 2972 head.write_buf = start; 2973 tomoyo_parse_policy(&head, start); 2974 start = end + 1; 2975 } 2976 } 2977 tomoyo_read_unlock(idx); 2978 #ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 2979 tomoyo_check_profile(); 2980 #endif 2981 } 2982