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