1 /* 2 * security/tomoyo/file.c 3 * 4 * Implementation of the Domain-Based Mandatory Access Control. 5 * 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 7 * 8 * Version: 2.2.0 2009/04/01 9 * 10 */ 11 12 #include "common.h" 13 #include <linux/slab.h> 14 15 /* Keyword array for single path operations. */ 16 static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 17 [TOMOYO_TYPE_READ_WRITE] = "read/write", 18 [TOMOYO_TYPE_EXECUTE] = "execute", 19 [TOMOYO_TYPE_READ] = "read", 20 [TOMOYO_TYPE_WRITE] = "write", 21 [TOMOYO_TYPE_CREATE] = "create", 22 [TOMOYO_TYPE_UNLINK] = "unlink", 23 [TOMOYO_TYPE_MKDIR] = "mkdir", 24 [TOMOYO_TYPE_RMDIR] = "rmdir", 25 [TOMOYO_TYPE_MKFIFO] = "mkfifo", 26 [TOMOYO_TYPE_MKSOCK] = "mksock", 27 [TOMOYO_TYPE_MKBLOCK] = "mkblock", 28 [TOMOYO_TYPE_MKCHAR] = "mkchar", 29 [TOMOYO_TYPE_TRUNCATE] = "truncate", 30 [TOMOYO_TYPE_SYMLINK] = "symlink", 31 [TOMOYO_TYPE_REWRITE] = "rewrite", 32 [TOMOYO_TYPE_IOCTL] = "ioctl", 33 [TOMOYO_TYPE_CHMOD] = "chmod", 34 [TOMOYO_TYPE_CHOWN] = "chown", 35 [TOMOYO_TYPE_CHGRP] = "chgrp", 36 [TOMOYO_TYPE_CHROOT] = "chroot", 37 [TOMOYO_TYPE_MOUNT] = "mount", 38 [TOMOYO_TYPE_UMOUNT] = "unmount", 39 }; 40 41 /* Keyword array for double path operations. */ 42 static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = { 43 [TOMOYO_TYPE_LINK] = "link", 44 [TOMOYO_TYPE_RENAME] = "rename", 45 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", 46 }; 47 48 void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 49 { 50 if (!ptr) 51 return; 52 if (ptr->is_group) 53 tomoyo_put_path_group(ptr->group); 54 else 55 tomoyo_put_name(ptr->filename); 56 } 57 58 bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, 59 const struct tomoyo_name_union *ptr) 60 { 61 if (ptr->is_group) 62 return tomoyo_path_matches_group(name, ptr->group, 1); 63 return tomoyo_path_matches_pattern(name, ptr->filename); 64 } 65 66 static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info 67 *name, 68 const struct tomoyo_name_union 69 *ptr, const bool may_use_pattern) 70 { 71 if (ptr->is_group) 72 return tomoyo_path_matches_group(name, ptr->group, 73 may_use_pattern); 74 if (may_use_pattern || !ptr->filename->is_patterned) 75 return tomoyo_path_matches_pattern(name, ptr->filename); 76 return false; 77 } 78 79 /** 80 * tomoyo_path2keyword - Get the name of single path operation. 81 * 82 * @operation: Type of operation. 83 * 84 * Returns the name of single path operation. 85 */ 86 const char *tomoyo_path2keyword(const u8 operation) 87 { 88 return (operation < TOMOYO_MAX_PATH_OPERATION) 89 ? tomoyo_path_keyword[operation] : NULL; 90 } 91 92 /** 93 * tomoyo_path22keyword - Get the name of double path operation. 94 * 95 * @operation: Type of operation. 96 * 97 * Returns the name of double path operation. 98 */ 99 const char *tomoyo_path22keyword(const u8 operation) 100 { 101 return (operation < TOMOYO_MAX_PATH2_OPERATION) 102 ? tomoyo_path2_keyword[operation] : NULL; 103 } 104 105 /** 106 * tomoyo_strendswith - Check whether the token ends with the given token. 107 * 108 * @name: The token to check. 109 * @tail: The token to find. 110 * 111 * Returns true if @name ends with @tail, false otherwise. 112 */ 113 static bool tomoyo_strendswith(const char *name, const char *tail) 114 { 115 int len; 116 117 if (!name || !tail) 118 return false; 119 len = strlen(name) - strlen(tail); 120 return len >= 0 && !strcmp(name + len, tail); 121 } 122 123 /** 124 * tomoyo_get_path - Get realpath. 125 * 126 * @path: Pointer to "struct path". 127 * 128 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 129 */ 130 static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 131 { 132 int error; 133 struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf), 134 GFP_NOFS); 135 136 if (!buf) 137 return NULL; 138 /* Reserve one byte for appending "/". */ 139 error = tomoyo_realpath_from_path2(path, buf->body, 140 sizeof(buf->body) - 2); 141 if (!error) { 142 buf->head.name = buf->body; 143 tomoyo_fill_path_info(&buf->head); 144 return &buf->head; 145 } 146 kfree(buf); 147 return NULL; 148 } 149 150 static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 151 const char *filename2, 152 struct tomoyo_domain_info *const domain, 153 const bool is_delete); 154 static int tomoyo_update_path_acl(const u8 type, const char *filename, 155 struct tomoyo_domain_info *const domain, 156 const bool is_delete); 157 158 /* 159 * tomoyo_globally_readable_list is used for holding list of pathnames which 160 * are by default allowed to be open()ed for reading by any process. 161 * 162 * An entry is added by 163 * 164 * # echo 'allow_read /lib/libc-2.5.so' > \ 165 * /sys/kernel/security/tomoyo/exception_policy 166 * 167 * and is deleted by 168 * 169 * # echo 'delete allow_read /lib/libc-2.5.so' > \ 170 * /sys/kernel/security/tomoyo/exception_policy 171 * 172 * and all entries are retrieved by 173 * 174 * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy 175 * 176 * In the example above, any process is allowed to 177 * open("/lib/libc-2.5.so", O_RDONLY). 178 * One exception is, if the domain which current process belongs to is marked 179 * as "ignore_global_allow_read", current process can't do so unless explicitly 180 * given "allow_read /lib/libc-2.5.so" to the domain which current process 181 * belongs to. 182 */ 183 LIST_HEAD(tomoyo_globally_readable_list); 184 185 /** 186 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. 187 * 188 * @filename: Filename unconditionally permitted to open() for reading. 189 * @is_delete: True if it is a delete request. 190 * 191 * Returns 0 on success, negative value otherwise. 192 * 193 * Caller holds tomoyo_read_lock(). 194 */ 195 static int tomoyo_update_globally_readable_entry(const char *filename, 196 const bool is_delete) 197 { 198 struct tomoyo_globally_readable_file_entry *ptr; 199 struct tomoyo_globally_readable_file_entry e = { }; 200 int error = is_delete ? -ENOENT : -ENOMEM; 201 202 if (!tomoyo_is_correct_path(filename, 1, 0, -1)) 203 return -EINVAL; 204 e.filename = tomoyo_get_name(filename); 205 if (!e.filename) 206 return -ENOMEM; 207 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 208 goto out; 209 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 210 if (ptr->filename != e.filename) 211 continue; 212 ptr->is_deleted = is_delete; 213 error = 0; 214 break; 215 } 216 if (!is_delete && error) { 217 struct tomoyo_globally_readable_file_entry *entry = 218 tomoyo_commit_ok(&e, sizeof(e)); 219 if (entry) { 220 list_add_tail_rcu(&entry->list, 221 &tomoyo_globally_readable_list); 222 error = 0; 223 } 224 } 225 mutex_unlock(&tomoyo_policy_lock); 226 out: 227 tomoyo_put_name(e.filename); 228 return error; 229 } 230 231 /** 232 * tomoyo_is_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading. 233 * 234 * @filename: The filename to check. 235 * 236 * Returns true if any domain can open @filename for reading, false otherwise. 237 * 238 * Caller holds tomoyo_read_lock(). 239 */ 240 static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 241 filename) 242 { 243 struct tomoyo_globally_readable_file_entry *ptr; 244 bool found = false; 245 246 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 247 if (!ptr->is_deleted && 248 tomoyo_path_matches_pattern(filename, ptr->filename)) { 249 found = true; 250 break; 251 } 252 } 253 return found; 254 } 255 256 /** 257 * tomoyo_write_globally_readable_policy - Write "struct tomoyo_globally_readable_file_entry" list. 258 * 259 * @data: String to parse. 260 * @is_delete: True if it is a delete request. 261 * 262 * Returns 0 on success, negative value otherwise. 263 * 264 * Caller holds tomoyo_read_lock(). 265 */ 266 int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 267 { 268 return tomoyo_update_globally_readable_entry(data, is_delete); 269 } 270 271 /** 272 * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list. 273 * 274 * @head: Pointer to "struct tomoyo_io_buffer". 275 * 276 * Returns true on success, false otherwise. 277 * 278 * Caller holds tomoyo_read_lock(). 279 */ 280 bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 281 { 282 struct list_head *pos; 283 bool done = true; 284 285 list_for_each_cookie(pos, head->read_var2, 286 &tomoyo_globally_readable_list) { 287 struct tomoyo_globally_readable_file_entry *ptr; 288 ptr = list_entry(pos, 289 struct tomoyo_globally_readable_file_entry, 290 list); 291 if (ptr->is_deleted) 292 continue; 293 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n", 294 ptr->filename->name); 295 if (!done) 296 break; 297 } 298 return done; 299 } 300 301 /* tomoyo_pattern_list is used for holding list of pathnames which are used for 302 * converting pathnames to pathname patterns during learning mode. 303 * 304 * An entry is added by 305 * 306 * # echo 'file_pattern /proc/\$/mounts' > \ 307 * /sys/kernel/security/tomoyo/exception_policy 308 * 309 * and is deleted by 310 * 311 * # echo 'delete file_pattern /proc/\$/mounts' > \ 312 * /sys/kernel/security/tomoyo/exception_policy 313 * 314 * and all entries are retrieved by 315 * 316 * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy 317 * 318 * In the example above, if a process which belongs to a domain which is in 319 * learning mode requested open("/proc/1/mounts", O_RDONLY), 320 * "allow_read /proc/\$/mounts" is automatically added to the domain which that 321 * process belongs to. 322 * 323 * It is not a desirable behavior that we have to use /proc/\$/ instead of 324 * /proc/self/ when current process needs to access only current process's 325 * information. As of now, LSM version of TOMOYO is using __d_path() for 326 * calculating pathname. Non LSM version of TOMOYO is using its own function 327 * which pretends as if /proc/self/ is not a symlink; so that we can forbid 328 * current process from accessing other process's information. 329 */ 330 LIST_HEAD(tomoyo_pattern_list); 331 332 /** 333 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. 334 * 335 * @pattern: Pathname pattern. 336 * @is_delete: True if it is a delete request. 337 * 338 * Returns 0 on success, negative value otherwise. 339 * 340 * Caller holds tomoyo_read_lock(). 341 */ 342 static int tomoyo_update_file_pattern_entry(const char *pattern, 343 const bool is_delete) 344 { 345 struct tomoyo_pattern_entry *ptr; 346 struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) }; 347 int error = is_delete ? -ENOENT : -ENOMEM; 348 349 if (!e.pattern) 350 return error; 351 if (!e.pattern->is_patterned) 352 goto out; 353 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 354 goto out; 355 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 356 if (e.pattern != ptr->pattern) 357 continue; 358 ptr->is_deleted = is_delete; 359 error = 0; 360 break; 361 } 362 if (!is_delete && error) { 363 struct tomoyo_pattern_entry *entry = 364 tomoyo_commit_ok(&e, sizeof(e)); 365 if (entry) { 366 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list); 367 error = 0; 368 } 369 } 370 mutex_unlock(&tomoyo_policy_lock); 371 out: 372 tomoyo_put_name(e.pattern); 373 return error; 374 } 375 376 /** 377 * tomoyo_get_file_pattern - Get patterned pathname. 378 * 379 * @filename: The filename to find patterned pathname. 380 * 381 * Returns pointer to pathname pattern if matched, @filename otherwise. 382 * 383 * Caller holds tomoyo_read_lock(). 384 */ 385 static const struct tomoyo_path_info * 386 tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 387 { 388 struct tomoyo_pattern_entry *ptr; 389 const struct tomoyo_path_info *pattern = NULL; 390 391 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 392 if (ptr->is_deleted) 393 continue; 394 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 395 continue; 396 pattern = ptr->pattern; 397 if (tomoyo_strendswith(pattern->name, "/\\*")) { 398 /* Do nothing. Try to find the better match. */ 399 } else { 400 /* This would be the better match. Use this. */ 401 break; 402 } 403 } 404 if (pattern) 405 filename = pattern; 406 return filename; 407 } 408 409 /** 410 * tomoyo_write_pattern_policy - Write "struct tomoyo_pattern_entry" list. 411 * 412 * @data: String to parse. 413 * @is_delete: True if it is a delete request. 414 * 415 * Returns 0 on success, negative value otherwise. 416 * 417 * Caller holds tomoyo_read_lock(). 418 */ 419 int tomoyo_write_pattern_policy(char *data, const bool is_delete) 420 { 421 return tomoyo_update_file_pattern_entry(data, is_delete); 422 } 423 424 /** 425 * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list. 426 * 427 * @head: Pointer to "struct tomoyo_io_buffer". 428 * 429 * Returns true on success, false otherwise. 430 * 431 * Caller holds tomoyo_read_lock(). 432 */ 433 bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 434 { 435 struct list_head *pos; 436 bool done = true; 437 438 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 439 struct tomoyo_pattern_entry *ptr; 440 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 441 if (ptr->is_deleted) 442 continue; 443 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN 444 "%s\n", ptr->pattern->name); 445 if (!done) 446 break; 447 } 448 return done; 449 } 450 451 /* 452 * tomoyo_no_rewrite_list is used for holding list of pathnames which are by 453 * default forbidden to modify already written content of a file. 454 * 455 * An entry is added by 456 * 457 * # echo 'deny_rewrite /var/log/messages' > \ 458 * /sys/kernel/security/tomoyo/exception_policy 459 * 460 * and is deleted by 461 * 462 * # echo 'delete deny_rewrite /var/log/messages' > \ 463 * /sys/kernel/security/tomoyo/exception_policy 464 * 465 * and all entries are retrieved by 466 * 467 * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy 468 * 469 * In the example above, if a process requested to rewrite /var/log/messages , 470 * the process can't rewrite unless the domain which that process belongs to 471 * has "allow_rewrite /var/log/messages" entry. 472 * 473 * It is not a desirable behavior that we have to add "\040(deleted)" suffix 474 * when we want to allow rewriting already unlink()ed file. As of now, 475 * LSM version of TOMOYO is using __d_path() for calculating pathname. 476 * Non LSM version of TOMOYO is using its own function which doesn't append 477 * " (deleted)" suffix if the file is already unlink()ed; so that we don't 478 * need to worry whether the file is already unlink()ed or not. 479 */ 480 LIST_HEAD(tomoyo_no_rewrite_list); 481 482 /** 483 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. 484 * 485 * @pattern: Pathname pattern that are not rewritable by default. 486 * @is_delete: True if it is a delete request. 487 * 488 * Returns 0 on success, negative value otherwise. 489 * 490 * Caller holds tomoyo_read_lock(). 491 */ 492 static int tomoyo_update_no_rewrite_entry(const char *pattern, 493 const bool is_delete) 494 { 495 struct tomoyo_no_rewrite_entry *ptr; 496 struct tomoyo_no_rewrite_entry e = { }; 497 int error = is_delete ? -ENOENT : -ENOMEM; 498 499 if (!tomoyo_is_correct_path(pattern, 0, 0, 0)) 500 return -EINVAL; 501 e.pattern = tomoyo_get_name(pattern); 502 if (!e.pattern) 503 return error; 504 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 505 goto out; 506 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 507 if (ptr->pattern != e.pattern) 508 continue; 509 ptr->is_deleted = is_delete; 510 error = 0; 511 break; 512 } 513 if (!is_delete && error) { 514 struct tomoyo_no_rewrite_entry *entry = 515 tomoyo_commit_ok(&e, sizeof(e)); 516 if (entry) { 517 list_add_tail_rcu(&entry->list, 518 &tomoyo_no_rewrite_list); 519 error = 0; 520 } 521 } 522 mutex_unlock(&tomoyo_policy_lock); 523 out: 524 tomoyo_put_name(e.pattern); 525 return error; 526 } 527 528 /** 529 * tomoyo_is_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. 530 * 531 * @filename: Filename to check. 532 * 533 * Returns true if @filename is specified by "deny_rewrite" directive, 534 * false otherwise. 535 * 536 * Caller holds tomoyo_read_lock(). 537 */ 538 static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename) 539 { 540 struct tomoyo_no_rewrite_entry *ptr; 541 bool found = false; 542 543 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 544 if (ptr->is_deleted) 545 continue; 546 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 547 continue; 548 found = true; 549 break; 550 } 551 return found; 552 } 553 554 /** 555 * tomoyo_write_no_rewrite_policy - Write "struct tomoyo_no_rewrite_entry" list. 556 * 557 * @data: String to parse. 558 * @is_delete: True if it is a delete request. 559 * 560 * Returns 0 on success, negative value otherwise. 561 * 562 * Caller holds tomoyo_read_lock(). 563 */ 564 int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 565 { 566 return tomoyo_update_no_rewrite_entry(data, is_delete); 567 } 568 569 /** 570 * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list. 571 * 572 * @head: Pointer to "struct tomoyo_io_buffer". 573 * 574 * Returns true on success, false otherwise. 575 * 576 * Caller holds tomoyo_read_lock(). 577 */ 578 bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 579 { 580 struct list_head *pos; 581 bool done = true; 582 583 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { 584 struct tomoyo_no_rewrite_entry *ptr; 585 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 586 if (ptr->is_deleted) 587 continue; 588 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE 589 "%s\n", ptr->pattern->name); 590 if (!done) 591 break; 592 } 593 return done; 594 } 595 596 /** 597 * tomoyo_update_file_acl - Update file's read/write/execute ACL. 598 * 599 * @filename: Filename. 600 * @perm: Permission (between 1 to 7). 601 * @domain: Pointer to "struct tomoyo_domain_info". 602 * @is_delete: True if it is a delete request. 603 * 604 * Returns 0 on success, negative value otherwise. 605 * 606 * This is legacy support interface for older policy syntax. 607 * Current policy syntax uses "allow_read/write" instead of "6", 608 * "allow_read" instead of "4", "allow_write" instead of "2", 609 * "allow_execute" instead of "1". 610 * 611 * Caller holds tomoyo_read_lock(). 612 */ 613 static int tomoyo_update_file_acl(const char *filename, u8 perm, 614 struct tomoyo_domain_info * const domain, 615 const bool is_delete) 616 { 617 if (perm > 7 || !perm) { 618 printk(KERN_DEBUG "%s: Invalid permission '%d %s'\n", 619 __func__, perm, filename); 620 return -EINVAL; 621 } 622 if (filename[0] != '@' && tomoyo_strendswith(filename, "/")) 623 /* 624 * Only 'allow_mkdir' and 'allow_rmdir' are valid for 625 * directory permissions. 626 */ 627 return 0; 628 if (perm & 4) 629 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain, 630 is_delete); 631 if (perm & 2) 632 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain, 633 is_delete); 634 if (perm & 1) 635 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain, 636 is_delete); 637 return 0; 638 } 639 640 /** 641 * tomoyo_path_acl2 - Check permission for single path operation. 642 * 643 * @domain: Pointer to "struct tomoyo_domain_info". 644 * @filename: Filename to check. 645 * @perm: Permission. 646 * @may_use_pattern: True if patterned ACL is permitted. 647 * 648 * Returns 0 on success, -EPERM otherwise. 649 * 650 * Caller holds tomoyo_read_lock(). 651 */ 652 static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain, 653 const struct tomoyo_path_info *filename, 654 const u32 perm, const bool may_use_pattern) 655 { 656 struct tomoyo_acl_info *ptr; 657 int error = -EPERM; 658 659 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 660 struct tomoyo_path_acl *acl; 661 if (ptr->type != TOMOYO_TYPE_PATH_ACL) 662 continue; 663 acl = container_of(ptr, struct tomoyo_path_acl, head); 664 if (perm <= 0xFFFF) { 665 if (!(acl->perm & perm)) 666 continue; 667 } else { 668 if (!(acl->perm_high & (perm >> 16))) 669 continue; 670 } 671 if (!tomoyo_compare_name_union_pattern(filename, &acl->name, 672 may_use_pattern)) 673 continue; 674 error = 0; 675 break; 676 } 677 return error; 678 } 679 680 /** 681 * tomoyo_check_file_acl - Check permission for opening files. 682 * 683 * @domain: Pointer to "struct tomoyo_domain_info". 684 * @filename: Filename to check. 685 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 686 * 687 * Returns 0 on success, -EPERM otherwise. 688 * 689 * Caller holds tomoyo_read_lock(). 690 */ 691 static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, 692 const struct tomoyo_path_info *filename, 693 const u8 operation) 694 { 695 u32 perm = 0; 696 697 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 698 return 0; 699 if (operation == 6) 700 perm = 1 << TOMOYO_TYPE_READ_WRITE; 701 else if (operation == 4) 702 perm = 1 << TOMOYO_TYPE_READ; 703 else if (operation == 2) 704 perm = 1 << TOMOYO_TYPE_WRITE; 705 else if (operation == 1) 706 perm = 1 << TOMOYO_TYPE_EXECUTE; 707 else 708 BUG(); 709 return tomoyo_path_acl2(domain, filename, perm, operation != 1); 710 } 711 712 /** 713 * tomoyo_check_file_perm2 - Check permission for opening files. 714 * 715 * @domain: Pointer to "struct tomoyo_domain_info". 716 * @filename: Filename to check. 717 * @perm: Mode ("read" or "write" or "read/write" or "execute"). 718 * @operation: Operation name passed used for verbose mode. 719 * @mode: Access control mode. 720 * 721 * Returns 0 on success, negative value otherwise. 722 * 723 * Caller holds tomoyo_read_lock(). 724 */ 725 static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 726 const struct tomoyo_path_info *filename, 727 const u8 perm, const char *operation, 728 const u8 mode) 729 { 730 const bool is_enforce = (mode == 3); 731 const char *msg = "<unknown>"; 732 int error = 0; 733 734 if (!filename) 735 return 0; 736 error = tomoyo_check_file_acl(domain, filename, perm); 737 if (error && perm == 4 && !domain->ignore_global_allow_read 738 && tomoyo_is_globally_readable_file(filename)) 739 error = 0; 740 if (perm == 6) 741 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE); 742 else if (perm == 4) 743 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ); 744 else if (perm == 2) 745 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE); 746 else if (perm == 1) 747 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE); 748 else 749 BUG(); 750 if (!error) 751 return 0; 752 if (tomoyo_verbose_mode(domain)) 753 printk(KERN_WARNING "TOMOYO-%s: Access '%s(%s) %s' denied " 754 "for %s\n", tomoyo_get_msg(is_enforce), msg, operation, 755 filename->name, tomoyo_get_last_name(domain)); 756 if (is_enforce) 757 return error; 758 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 759 /* Don't use patterns for execute permission. */ 760 const struct tomoyo_path_info *patterned_file = (perm != 1) ? 761 tomoyo_get_file_pattern(filename) : filename; 762 tomoyo_update_file_acl(patterned_file->name, perm, 763 domain, false); 764 } 765 return 0; 766 } 767 768 /** 769 * tomoyo_write_file_policy - Update file related list. 770 * 771 * @data: String to parse. 772 * @domain: Pointer to "struct tomoyo_domain_info". 773 * @is_delete: True if it is a delete request. 774 * 775 * Returns 0 on success, negative value otherwise. 776 * 777 * Caller holds tomoyo_read_lock(). 778 */ 779 int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 780 const bool is_delete) 781 { 782 char *filename = strchr(data, ' '); 783 char *filename2; 784 unsigned int perm; 785 u8 type; 786 787 if (!filename) 788 return -EINVAL; 789 *filename++ = '\0'; 790 if (sscanf(data, "%u", &perm) == 1) 791 return tomoyo_update_file_acl(filename, (u8) perm, domain, 792 is_delete); 793 if (strncmp(data, "allow_", 6)) 794 goto out; 795 data += 6; 796 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { 797 if (strcmp(data, tomoyo_path_keyword[type])) 798 continue; 799 return tomoyo_update_path_acl(type, filename, domain, 800 is_delete); 801 } 802 filename2 = strchr(filename, ' '); 803 if (!filename2) 804 goto out; 805 *filename2++ = '\0'; 806 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { 807 if (strcmp(data, tomoyo_path2_keyword[type])) 808 continue; 809 return tomoyo_update_path2_acl(type, filename, filename2, 810 domain, is_delete); 811 } 812 out: 813 return -EINVAL; 814 } 815 816 /** 817 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 818 * 819 * @type: Type of operation. 820 * @filename: Filename. 821 * @domain: Pointer to "struct tomoyo_domain_info". 822 * @is_delete: True if it is a delete request. 823 * 824 * Returns 0 on success, negative value otherwise. 825 * 826 * Caller holds tomoyo_read_lock(). 827 */ 828 static int tomoyo_update_path_acl(const u8 type, const char *filename, 829 struct tomoyo_domain_info *const domain, 830 const bool is_delete) 831 { 832 static const u32 tomoyo_rw_mask = 833 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE); 834 const u32 perm = 1 << type; 835 struct tomoyo_acl_info *ptr; 836 struct tomoyo_path_acl e = { 837 .head.type = TOMOYO_TYPE_PATH_ACL, 838 .perm_high = perm >> 16, 839 .perm = perm 840 }; 841 int error = is_delete ? -ENOENT : -ENOMEM; 842 843 if (type == TOMOYO_TYPE_READ_WRITE) 844 e.perm |= tomoyo_rw_mask; 845 if (!domain) 846 return -EINVAL; 847 if (!tomoyo_parse_name_union(filename, &e.name)) 848 return -EINVAL; 849 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 850 goto out; 851 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 852 struct tomoyo_path_acl *acl = 853 container_of(ptr, struct tomoyo_path_acl, head); 854 if (!tomoyo_is_same_path_acl(acl, &e)) 855 continue; 856 if (is_delete) { 857 if (perm <= 0xFFFF) 858 acl->perm &= ~perm; 859 else 860 acl->perm_high &= ~(perm >> 16); 861 if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask) 862 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE); 863 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))) 864 acl->perm &= ~tomoyo_rw_mask; 865 } else { 866 if (perm <= 0xFFFF) 867 acl->perm |= perm; 868 else 869 acl->perm_high |= (perm >> 16); 870 if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask) 871 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE; 872 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)) 873 acl->perm |= tomoyo_rw_mask; 874 } 875 error = 0; 876 break; 877 } 878 if (!is_delete && error) { 879 struct tomoyo_path_acl *entry = 880 tomoyo_commit_ok(&e, sizeof(e)); 881 if (entry) { 882 list_add_tail_rcu(&entry->head.list, 883 &domain->acl_info_list); 884 error = 0; 885 } 886 } 887 mutex_unlock(&tomoyo_policy_lock); 888 out: 889 tomoyo_put_name_union(&e.name); 890 return error; 891 } 892 893 /** 894 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 895 * 896 * @type: Type of operation. 897 * @filename1: First filename. 898 * @filename2: Second filename. 899 * @domain: Pointer to "struct tomoyo_domain_info". 900 * @is_delete: True if it is a delete request. 901 * 902 * Returns 0 on success, negative value otherwise. 903 * 904 * Caller holds tomoyo_read_lock(). 905 */ 906 static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 907 const char *filename2, 908 struct tomoyo_domain_info *const domain, 909 const bool is_delete) 910 { 911 const u8 perm = 1 << type; 912 struct tomoyo_path2_acl e = { 913 .head.type = TOMOYO_TYPE_PATH2_ACL, 914 .perm = perm 915 }; 916 struct tomoyo_acl_info *ptr; 917 int error = is_delete ? -ENOENT : -ENOMEM; 918 919 if (!domain) 920 return -EINVAL; 921 if (!tomoyo_parse_name_union(filename1, &e.name1) || 922 !tomoyo_parse_name_union(filename2, &e.name2)) 923 goto out; 924 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 925 goto out; 926 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 927 struct tomoyo_path2_acl *acl = 928 container_of(ptr, struct tomoyo_path2_acl, head); 929 if (!tomoyo_is_same_path2_acl(acl, &e)) 930 continue; 931 if (is_delete) 932 acl->perm &= ~perm; 933 else 934 acl->perm |= perm; 935 error = 0; 936 break; 937 } 938 if (!is_delete && error) { 939 struct tomoyo_path2_acl *entry = 940 tomoyo_commit_ok(&e, sizeof(e)); 941 if (entry) { 942 list_add_tail_rcu(&entry->head.list, 943 &domain->acl_info_list); 944 error = 0; 945 } 946 } 947 mutex_unlock(&tomoyo_policy_lock); 948 out: 949 tomoyo_put_name_union(&e.name1); 950 tomoyo_put_name_union(&e.name2); 951 return error; 952 } 953 954 /** 955 * tomoyo_path_acl - Check permission for single path operation. 956 * 957 * @domain: Pointer to "struct tomoyo_domain_info". 958 * @type: Type of operation. 959 * @filename: Filename to check. 960 * 961 * Returns 0 on success, negative value otherwise. 962 * 963 * Caller holds tomoyo_read_lock(). 964 */ 965 static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type, 966 const struct tomoyo_path_info *filename) 967 { 968 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 969 return 0; 970 return tomoyo_path_acl2(domain, filename, 1 << type, 1); 971 } 972 973 /** 974 * tomoyo_path2_acl - Check permission for double path operation. 975 * 976 * @domain: Pointer to "struct tomoyo_domain_info". 977 * @type: Type of operation. 978 * @filename1: First filename to check. 979 * @filename2: Second filename to check. 980 * 981 * Returns 0 on success, -EPERM otherwise. 982 * 983 * Caller holds tomoyo_read_lock(). 984 */ 985 static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain, 986 const u8 type, 987 const struct tomoyo_path_info *filename1, 988 const struct tomoyo_path_info *filename2) 989 { 990 struct tomoyo_acl_info *ptr; 991 const u8 perm = 1 << type; 992 int error = -EPERM; 993 994 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 995 return 0; 996 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 997 struct tomoyo_path2_acl *acl; 998 if (ptr->type != TOMOYO_TYPE_PATH2_ACL) 999 continue; 1000 acl = container_of(ptr, struct tomoyo_path2_acl, head); 1001 if (!(acl->perm & perm)) 1002 continue; 1003 if (!tomoyo_compare_name_union(filename1, &acl->name1)) 1004 continue; 1005 if (!tomoyo_compare_name_union(filename2, &acl->name2)) 1006 continue; 1007 error = 0; 1008 break; 1009 } 1010 return error; 1011 } 1012 1013 /** 1014 * tomoyo_path_permission2 - Check permission for single path operation. 1015 * 1016 * @domain: Pointer to "struct tomoyo_domain_info". 1017 * @operation: Type of operation. 1018 * @filename: Filename to check. 1019 * @mode: Access control mode. 1020 * 1021 * Returns 0 on success, negative value otherwise. 1022 * 1023 * Caller holds tomoyo_read_lock(). 1024 */ 1025 static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain, 1026 u8 operation, 1027 const struct tomoyo_path_info *filename, 1028 const u8 mode) 1029 { 1030 const char *msg; 1031 int error; 1032 const bool is_enforce = (mode == 3); 1033 1034 if (!mode) 1035 return 0; 1036 next: 1037 error = tomoyo_path_acl(domain, operation, filename); 1038 msg = tomoyo_path2keyword(operation); 1039 if (!error) 1040 goto ok; 1041 if (tomoyo_verbose_mode(domain)) 1042 printk(KERN_WARNING "TOMOYO-%s: Access '%s %s' denied for %s\n", 1043 tomoyo_get_msg(is_enforce), msg, filename->name, 1044 tomoyo_get_last_name(domain)); 1045 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1046 const char *name = tomoyo_get_file_pattern(filename)->name; 1047 tomoyo_update_path_acl(operation, name, domain, false); 1048 } 1049 if (!is_enforce) 1050 error = 0; 1051 ok: 1052 /* 1053 * Since "allow_truncate" doesn't imply "allow_rewrite" permission, 1054 * we need to check "allow_rewrite" permission if the filename is 1055 * specified by "deny_rewrite" keyword. 1056 */ 1057 if (!error && operation == TOMOYO_TYPE_TRUNCATE && 1058 tomoyo_is_no_rewrite_file(filename)) { 1059 operation = TOMOYO_TYPE_REWRITE; 1060 goto next; 1061 } 1062 return error; 1063 } 1064 1065 /** 1066 * tomoyo_check_exec_perm - Check permission for "execute". 1067 * 1068 * @domain: Pointer to "struct tomoyo_domain_info". 1069 * @filename: Check permission for "execute". 1070 * 1071 * Returns 0 on success, negativevalue otherwise. 1072 * 1073 * Caller holds tomoyo_read_lock(). 1074 */ 1075 int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1076 const struct tomoyo_path_info *filename) 1077 { 1078 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1079 1080 if (!mode) 1081 return 0; 1082 return tomoyo_check_file_perm2(domain, filename, 1, "do_execve", mode); 1083 } 1084 1085 /** 1086 * tomoyo_check_open_permission - Check permission for "read" and "write". 1087 * 1088 * @domain: Pointer to "struct tomoyo_domain_info". 1089 * @path: Pointer to "struct path". 1090 * @flag: Flags for open(). 1091 * 1092 * Returns 0 on success, negative value otherwise. 1093 */ 1094 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 1095 struct path *path, const int flag) 1096 { 1097 const u8 acc_mode = ACC_MODE(flag); 1098 int error = -ENOMEM; 1099 struct tomoyo_path_info *buf; 1100 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1101 const bool is_enforce = (mode == 3); 1102 int idx; 1103 1104 if (!mode || !path->mnt) 1105 return 0; 1106 if (acc_mode == 0) 1107 return 0; 1108 if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)) 1109 /* 1110 * I don't check directories here because mkdir() and rmdir() 1111 * don't call me. 1112 */ 1113 return 0; 1114 idx = tomoyo_read_lock(); 1115 buf = tomoyo_get_path(path); 1116 if (!buf) 1117 goto out; 1118 error = 0; 1119 /* 1120 * If the filename is specified by "deny_rewrite" keyword, 1121 * we need to check "allow_rewrite" permission when the filename is not 1122 * opened for append mode or the filename is truncated at open time. 1123 */ 1124 if ((acc_mode & MAY_WRITE) && 1125 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1126 (tomoyo_is_no_rewrite_file(buf))) { 1127 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, 1128 buf, mode); 1129 } 1130 if (!error) 1131 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open", 1132 mode); 1133 if (!error && (flag & O_TRUNC)) 1134 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE, 1135 buf, mode); 1136 out: 1137 kfree(buf); 1138 tomoyo_read_unlock(idx); 1139 if (!is_enforce) 1140 error = 0; 1141 return error; 1142 } 1143 1144 /** 1145 * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount". 1146 * 1147 * @operation: Type of operation. 1148 * @path: Pointer to "struct path". 1149 * 1150 * Returns 0 on success, negative value otherwise. 1151 */ 1152 int tomoyo_path_perm(const u8 operation, struct path *path) 1153 { 1154 int error = -ENOMEM; 1155 struct tomoyo_path_info *buf; 1156 struct tomoyo_domain_info *domain = tomoyo_domain(); 1157 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1158 const bool is_enforce = (mode == 3); 1159 int idx; 1160 1161 if (!mode || !path->mnt) 1162 return 0; 1163 idx = tomoyo_read_lock(); 1164 buf = tomoyo_get_path(path); 1165 if (!buf) 1166 goto out; 1167 switch (operation) { 1168 case TOMOYO_TYPE_MKDIR: 1169 case TOMOYO_TYPE_RMDIR: 1170 case TOMOYO_TYPE_CHROOT: 1171 if (!buf->is_dir) { 1172 /* 1173 * tomoyo_get_path() reserves space for appending "/." 1174 */ 1175 strcat((char *) buf->name, "/"); 1176 tomoyo_fill_path_info(buf); 1177 } 1178 } 1179 error = tomoyo_path_permission2(domain, operation, buf, mode); 1180 out: 1181 kfree(buf); 1182 tomoyo_read_unlock(idx); 1183 if (!is_enforce) 1184 error = 0; 1185 return error; 1186 } 1187 1188 /** 1189 * tomoyo_check_rewrite_permission - Check permission for "rewrite". 1190 * 1191 * @filp: Pointer to "struct file". 1192 * 1193 * Returns 0 on success, negative value otherwise. 1194 */ 1195 int tomoyo_check_rewrite_permission(struct file *filp) 1196 { 1197 int error = -ENOMEM; 1198 struct tomoyo_domain_info *domain = tomoyo_domain(); 1199 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1200 const bool is_enforce = (mode == 3); 1201 struct tomoyo_path_info *buf; 1202 int idx; 1203 1204 if (!mode || !filp->f_path.mnt) 1205 return 0; 1206 1207 idx = tomoyo_read_lock(); 1208 buf = tomoyo_get_path(&filp->f_path); 1209 if (!buf) 1210 goto out; 1211 if (!tomoyo_is_no_rewrite_file(buf)) { 1212 error = 0; 1213 goto out; 1214 } 1215 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode); 1216 out: 1217 kfree(buf); 1218 tomoyo_read_unlock(idx); 1219 if (!is_enforce) 1220 error = 0; 1221 return error; 1222 } 1223 1224 /** 1225 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root". 1226 * 1227 * @operation: Type of operation. 1228 * @path1: Pointer to "struct path". 1229 * @path2: Pointer to "struct path". 1230 * 1231 * Returns 0 on success, negative value otherwise. 1232 */ 1233 int tomoyo_path2_perm(const u8 operation, struct path *path1, 1234 struct path *path2) 1235 { 1236 int error = -ENOMEM; 1237 struct tomoyo_path_info *buf1, *buf2; 1238 struct tomoyo_domain_info *domain = tomoyo_domain(); 1239 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1240 const bool is_enforce = (mode == 3); 1241 const char *msg; 1242 int idx; 1243 1244 if (!mode || !path1->mnt || !path2->mnt) 1245 return 0; 1246 idx = tomoyo_read_lock(); 1247 buf1 = tomoyo_get_path(path1); 1248 buf2 = tomoyo_get_path(path2); 1249 if (!buf1 || !buf2) 1250 goto out; 1251 { 1252 struct dentry *dentry = path1->dentry; 1253 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { 1254 /* 1255 * tomoyo_get_path() reserves space for appending "/." 1256 */ 1257 if (!buf1->is_dir) { 1258 strcat((char *) buf1->name, "/"); 1259 tomoyo_fill_path_info(buf1); 1260 } 1261 if (!buf2->is_dir) { 1262 strcat((char *) buf2->name, "/"); 1263 tomoyo_fill_path_info(buf2); 1264 } 1265 } 1266 } 1267 error = tomoyo_path2_acl(domain, operation, buf1, buf2); 1268 msg = tomoyo_path22keyword(operation); 1269 if (!error) 1270 goto out; 1271 if (tomoyo_verbose_mode(domain)) 1272 printk(KERN_WARNING "TOMOYO-%s: Access '%s %s %s' " 1273 "denied for %s\n", tomoyo_get_msg(is_enforce), 1274 msg, buf1->name, buf2->name, 1275 tomoyo_get_last_name(domain)); 1276 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1277 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1278 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1279 tomoyo_update_path2_acl(operation, name1, name2, domain, 1280 false); 1281 } 1282 out: 1283 kfree(buf1); 1284 kfree(buf2); 1285 tomoyo_read_unlock(idx); 1286 if (!is_enforce) 1287 error = 0; 1288 return error; 1289 } 1290