file.c revision a1f9bb6a375a8dbf7797ffbd6739c46b338a77f7
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 operations with one pathname. */ 16static 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_UNLINK] = "unlink", 22 [TOMOYO_TYPE_RMDIR] = "rmdir", 23 [TOMOYO_TYPE_TRUNCATE] = "truncate", 24 [TOMOYO_TYPE_SYMLINK] = "symlink", 25 [TOMOYO_TYPE_REWRITE] = "rewrite", 26 [TOMOYO_TYPE_CHROOT] = "chroot", 27 [TOMOYO_TYPE_MOUNT] = "mount", 28 [TOMOYO_TYPE_UMOUNT] = "unmount", 29}; 30 31/* Keyword array for operations with one pathname and three numbers. */ 32static const char *tomoyo_path_number3_keyword 33[TOMOYO_MAX_PATH_NUMBER3_OPERATION] = { 34 [TOMOYO_TYPE_MKBLOCK] = "mkblock", 35 [TOMOYO_TYPE_MKCHAR] = "mkchar", 36}; 37 38/* Keyword array for operations with two pathnames. */ 39static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = { 40 [TOMOYO_TYPE_LINK] = "link", 41 [TOMOYO_TYPE_RENAME] = "rename", 42 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", 43}; 44 45/* Keyword array for operations with one pathname and one number. */ 46static const char *tomoyo_path_number_keyword 47[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 48 [TOMOYO_TYPE_CREATE] = "create", 49 [TOMOYO_TYPE_MKDIR] = "mkdir", 50 [TOMOYO_TYPE_MKFIFO] = "mkfifo", 51 [TOMOYO_TYPE_MKSOCK] = "mksock", 52 [TOMOYO_TYPE_IOCTL] = "ioctl", 53 [TOMOYO_TYPE_CHMOD] = "chmod", 54 [TOMOYO_TYPE_CHOWN] = "chown", 55 [TOMOYO_TYPE_CHGRP] = "chgrp", 56}; 57 58void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 59{ 60 if (!ptr) 61 return; 62 if (ptr->is_group) 63 tomoyo_put_path_group(ptr->group); 64 else 65 tomoyo_put_name(ptr->filename); 66} 67 68bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, 69 const struct tomoyo_name_union *ptr) 70{ 71 if (ptr->is_group) 72 return tomoyo_path_matches_group(name, ptr->group, 1); 73 return tomoyo_path_matches_pattern(name, ptr->filename); 74} 75 76static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info 77 *name, 78 const struct tomoyo_name_union 79 *ptr, const bool may_use_pattern) 80{ 81 if (ptr->is_group) 82 return tomoyo_path_matches_group(name, ptr->group, 83 may_use_pattern); 84 if (may_use_pattern || !ptr->filename->is_patterned) 85 return tomoyo_path_matches_pattern(name, ptr->filename); 86 return false; 87} 88 89void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 90{ 91 if (ptr && ptr->is_group) 92 tomoyo_put_number_group(ptr->group); 93} 94 95bool tomoyo_compare_number_union(const unsigned long value, 96 const struct tomoyo_number_union *ptr) 97{ 98 if (ptr->is_group) 99 return tomoyo_number_matches_group(value, value, ptr->group); 100 return value >= ptr->values[0] && value <= ptr->values[1]; 101} 102 103/** 104 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members. 105 * 106 * @r: Pointer to "struct tomoyo_request_info" to initialize. 107 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain(). 108 * 109 * Returns mode. 110 */ 111static int tomoyo_init_request_info(struct tomoyo_request_info *r, 112 struct tomoyo_domain_info *domain) 113{ 114 memset(r, 0, sizeof(*r)); 115 if (!domain) 116 domain = tomoyo_domain(); 117 r->domain = domain; 118 r->mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 119 return r->mode; 120} 121 122static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...) 123 __attribute__ ((format(printf, 2, 3))); 124/** 125 * tomoyo_warn_log - Print warning or error message on console. 126 * 127 * @r: Pointer to "struct tomoyo_request_info". 128 * @fmt: The printf()'s format string, followed by parameters. 129 */ 130static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...) 131{ 132 int len = PAGE_SIZE; 133 va_list args; 134 char *buffer; 135 if (!tomoyo_verbose_mode(r->domain)) 136 return; 137 while (1) { 138 int len2; 139 buffer = kmalloc(len, GFP_NOFS); 140 if (!buffer) 141 return; 142 va_start(args, fmt); 143 len2 = vsnprintf(buffer, len - 1, fmt, args); 144 va_end(args); 145 if (len2 <= len - 1) { 146 buffer[len2] = '\0'; 147 break; 148 } 149 len = len2 + 1; 150 kfree(buffer); 151 } 152 printk(KERN_WARNING "TOMOYO-%s: Access %s denied for %s\n", 153 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING", 154 buffer, tomoyo_get_last_name(r->domain)); 155 kfree(buffer); 156} 157 158/** 159 * tomoyo_path2keyword - Get the name of single path operation. 160 * 161 * @operation: Type of operation. 162 * 163 * Returns the name of single path operation. 164 */ 165const char *tomoyo_path2keyword(const u8 operation) 166{ 167 return (operation < TOMOYO_MAX_PATH_OPERATION) 168 ? tomoyo_path_keyword[operation] : NULL; 169} 170 171/** 172 * tomoyo_path_number32keyword - Get the name of path/number/number/number operations. 173 * 174 * @operation: Type of operation. 175 * 176 * Returns the name of path/number/number/number operation. 177 */ 178const char *tomoyo_path_number32keyword(const u8 operation) 179{ 180 return (operation < TOMOYO_MAX_PATH_NUMBER3_OPERATION) 181 ? tomoyo_path_number3_keyword[operation] : NULL; 182} 183 184/** 185 * tomoyo_path22keyword - Get the name of double path operation. 186 * 187 * @operation: Type of operation. 188 * 189 * Returns the name of double path operation. 190 */ 191const char *tomoyo_path22keyword(const u8 operation) 192{ 193 return (operation < TOMOYO_MAX_PATH2_OPERATION) 194 ? tomoyo_path2_keyword[operation] : NULL; 195} 196 197/** 198 * tomoyo_path_number2keyword - Get the name of path/number operations. 199 * 200 * @operation: Type of operation. 201 * 202 * Returns the name of path/number operation. 203 */ 204const char *tomoyo_path_number2keyword(const u8 operation) 205{ 206 return (operation < TOMOYO_MAX_PATH_NUMBER_OPERATION) 207 ? tomoyo_path_number_keyword[operation] : NULL; 208} 209 210/** 211 * tomoyo_strendswith - Check whether the token ends with the given token. 212 * 213 * @name: The token to check. 214 * @tail: The token to find. 215 * 216 * Returns true if @name ends with @tail, false otherwise. 217 */ 218static bool tomoyo_strendswith(const char *name, const char *tail) 219{ 220 int len; 221 222 if (!name || !tail) 223 return false; 224 len = strlen(name) - strlen(tail); 225 return len >= 0 && !strcmp(name + len, tail); 226} 227 228/** 229 * tomoyo_get_path - Get realpath. 230 * 231 * @path: Pointer to "struct path". 232 * 233 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 234 */ 235static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 236{ 237 int error; 238 struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf), 239 GFP_NOFS); 240 241 if (!buf) 242 return NULL; 243 /* Reserve one byte for appending "/". */ 244 error = tomoyo_realpath_from_path2(path, buf->body, 245 sizeof(buf->body) - 2); 246 if (!error) { 247 buf->head.name = buf->body; 248 tomoyo_fill_path_info(&buf->head); 249 return &buf->head; 250 } 251 kfree(buf); 252 return NULL; 253} 254 255static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 256 const char *filename2, 257 struct tomoyo_domain_info *const domain, 258 const bool is_delete); 259static int tomoyo_update_path_acl(const u8 type, const char *filename, 260 struct tomoyo_domain_info *const domain, 261 const bool is_delete); 262 263/* 264 * tomoyo_globally_readable_list is used for holding list of pathnames which 265 * are by default allowed to be open()ed for reading by any process. 266 * 267 * An entry is added by 268 * 269 * # echo 'allow_read /lib/libc-2.5.so' > \ 270 * /sys/kernel/security/tomoyo/exception_policy 271 * 272 * and is deleted by 273 * 274 * # echo 'delete allow_read /lib/libc-2.5.so' > \ 275 * /sys/kernel/security/tomoyo/exception_policy 276 * 277 * and all entries are retrieved by 278 * 279 * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy 280 * 281 * In the example above, any process is allowed to 282 * open("/lib/libc-2.5.so", O_RDONLY). 283 * One exception is, if the domain which current process belongs to is marked 284 * as "ignore_global_allow_read", current process can't do so unless explicitly 285 * given "allow_read /lib/libc-2.5.so" to the domain which current process 286 * belongs to. 287 */ 288LIST_HEAD(tomoyo_globally_readable_list); 289 290/** 291 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. 292 * 293 * @filename: Filename unconditionally permitted to open() for reading. 294 * @is_delete: True if it is a delete request. 295 * 296 * Returns 0 on success, negative value otherwise. 297 * 298 * Caller holds tomoyo_read_lock(). 299 */ 300static int tomoyo_update_globally_readable_entry(const char *filename, 301 const bool is_delete) 302{ 303 struct tomoyo_globally_readable_file_entry *ptr; 304 struct tomoyo_globally_readable_file_entry e = { }; 305 int error = is_delete ? -ENOENT : -ENOMEM; 306 307 if (!tomoyo_is_correct_path(filename, 1, 0, -1)) 308 return -EINVAL; 309 e.filename = tomoyo_get_name(filename); 310 if (!e.filename) 311 return -ENOMEM; 312 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 313 goto out; 314 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 315 if (ptr->filename != e.filename) 316 continue; 317 ptr->is_deleted = is_delete; 318 error = 0; 319 break; 320 } 321 if (!is_delete && error) { 322 struct tomoyo_globally_readable_file_entry *entry = 323 tomoyo_commit_ok(&e, sizeof(e)); 324 if (entry) { 325 list_add_tail_rcu(&entry->list, 326 &tomoyo_globally_readable_list); 327 error = 0; 328 } 329 } 330 mutex_unlock(&tomoyo_policy_lock); 331 out: 332 tomoyo_put_name(e.filename); 333 return error; 334} 335 336/** 337 * tomoyo_is_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading. 338 * 339 * @filename: The filename to check. 340 * 341 * Returns true if any domain can open @filename for reading, false otherwise. 342 * 343 * Caller holds tomoyo_read_lock(). 344 */ 345static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 346 filename) 347{ 348 struct tomoyo_globally_readable_file_entry *ptr; 349 bool found = false; 350 351 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { 352 if (!ptr->is_deleted && 353 tomoyo_path_matches_pattern(filename, ptr->filename)) { 354 found = true; 355 break; 356 } 357 } 358 return found; 359} 360 361/** 362 * tomoyo_write_globally_readable_policy - Write "struct tomoyo_globally_readable_file_entry" list. 363 * 364 * @data: String to parse. 365 * @is_delete: True if it is a delete request. 366 * 367 * Returns 0 on success, negative value otherwise. 368 * 369 * Caller holds tomoyo_read_lock(). 370 */ 371int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 372{ 373 return tomoyo_update_globally_readable_entry(data, is_delete); 374} 375 376/** 377 * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list. 378 * 379 * @head: Pointer to "struct tomoyo_io_buffer". 380 * 381 * Returns true on success, false otherwise. 382 * 383 * Caller holds tomoyo_read_lock(). 384 */ 385bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 386{ 387 struct list_head *pos; 388 bool done = true; 389 390 list_for_each_cookie(pos, head->read_var2, 391 &tomoyo_globally_readable_list) { 392 struct tomoyo_globally_readable_file_entry *ptr; 393 ptr = list_entry(pos, 394 struct tomoyo_globally_readable_file_entry, 395 list); 396 if (ptr->is_deleted) 397 continue; 398 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n", 399 ptr->filename->name); 400 if (!done) 401 break; 402 } 403 return done; 404} 405 406/* tomoyo_pattern_list is used for holding list of pathnames which are used for 407 * converting pathnames to pathname patterns during learning mode. 408 * 409 * An entry is added by 410 * 411 * # echo 'file_pattern /proc/\$/mounts' > \ 412 * /sys/kernel/security/tomoyo/exception_policy 413 * 414 * and is deleted by 415 * 416 * # echo 'delete file_pattern /proc/\$/mounts' > \ 417 * /sys/kernel/security/tomoyo/exception_policy 418 * 419 * and all entries are retrieved by 420 * 421 * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy 422 * 423 * In the example above, if a process which belongs to a domain which is in 424 * learning mode requested open("/proc/1/mounts", O_RDONLY), 425 * "allow_read /proc/\$/mounts" is automatically added to the domain which that 426 * process belongs to. 427 * 428 * It is not a desirable behavior that we have to use /proc/\$/ instead of 429 * /proc/self/ when current process needs to access only current process's 430 * information. As of now, LSM version of TOMOYO is using __d_path() for 431 * calculating pathname. Non LSM version of TOMOYO is using its own function 432 * which pretends as if /proc/self/ is not a symlink; so that we can forbid 433 * current process from accessing other process's information. 434 */ 435LIST_HEAD(tomoyo_pattern_list); 436 437/** 438 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. 439 * 440 * @pattern: Pathname pattern. 441 * @is_delete: True if it is a delete request. 442 * 443 * Returns 0 on success, negative value otherwise. 444 * 445 * Caller holds tomoyo_read_lock(). 446 */ 447static int tomoyo_update_file_pattern_entry(const char *pattern, 448 const bool is_delete) 449{ 450 struct tomoyo_pattern_entry *ptr; 451 struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) }; 452 int error = is_delete ? -ENOENT : -ENOMEM; 453 454 if (!e.pattern) 455 return error; 456 if (!e.pattern->is_patterned) 457 goto out; 458 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 459 goto out; 460 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 461 if (e.pattern != ptr->pattern) 462 continue; 463 ptr->is_deleted = is_delete; 464 error = 0; 465 break; 466 } 467 if (!is_delete && error) { 468 struct tomoyo_pattern_entry *entry = 469 tomoyo_commit_ok(&e, sizeof(e)); 470 if (entry) { 471 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list); 472 error = 0; 473 } 474 } 475 mutex_unlock(&tomoyo_policy_lock); 476 out: 477 tomoyo_put_name(e.pattern); 478 return error; 479} 480 481/** 482 * tomoyo_get_file_pattern - Get patterned pathname. 483 * 484 * @filename: The filename to find patterned pathname. 485 * 486 * Returns pointer to pathname pattern if matched, @filename otherwise. 487 * 488 * Caller holds tomoyo_read_lock(). 489 */ 490static const struct tomoyo_path_info * 491tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 492{ 493 struct tomoyo_pattern_entry *ptr; 494 const struct tomoyo_path_info *pattern = NULL; 495 496 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 497 if (ptr->is_deleted) 498 continue; 499 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 500 continue; 501 pattern = ptr->pattern; 502 if (tomoyo_strendswith(pattern->name, "/\\*")) { 503 /* Do nothing. Try to find the better match. */ 504 } else { 505 /* This would be the better match. Use this. */ 506 break; 507 } 508 } 509 if (pattern) 510 filename = pattern; 511 return filename; 512} 513 514/** 515 * tomoyo_write_pattern_policy - Write "struct tomoyo_pattern_entry" list. 516 * 517 * @data: String to parse. 518 * @is_delete: True if it is a delete request. 519 * 520 * Returns 0 on success, negative value otherwise. 521 * 522 * Caller holds tomoyo_read_lock(). 523 */ 524int tomoyo_write_pattern_policy(char *data, const bool is_delete) 525{ 526 return tomoyo_update_file_pattern_entry(data, is_delete); 527} 528 529/** 530 * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list. 531 * 532 * @head: Pointer to "struct tomoyo_io_buffer". 533 * 534 * Returns true on success, false otherwise. 535 * 536 * Caller holds tomoyo_read_lock(). 537 */ 538bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 539{ 540 struct list_head *pos; 541 bool done = true; 542 543 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 544 struct tomoyo_pattern_entry *ptr; 545 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 546 if (ptr->is_deleted) 547 continue; 548 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN 549 "%s\n", ptr->pattern->name); 550 if (!done) 551 break; 552 } 553 return done; 554} 555 556/* 557 * tomoyo_no_rewrite_list is used for holding list of pathnames which are by 558 * default forbidden to modify already written content of a file. 559 * 560 * An entry is added by 561 * 562 * # echo 'deny_rewrite /var/log/messages' > \ 563 * /sys/kernel/security/tomoyo/exception_policy 564 * 565 * and is deleted by 566 * 567 * # echo 'delete deny_rewrite /var/log/messages' > \ 568 * /sys/kernel/security/tomoyo/exception_policy 569 * 570 * and all entries are retrieved by 571 * 572 * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy 573 * 574 * In the example above, if a process requested to rewrite /var/log/messages , 575 * the process can't rewrite unless the domain which that process belongs to 576 * has "allow_rewrite /var/log/messages" entry. 577 * 578 * It is not a desirable behavior that we have to add "\040(deleted)" suffix 579 * when we want to allow rewriting already unlink()ed file. As of now, 580 * LSM version of TOMOYO is using __d_path() for calculating pathname. 581 * Non LSM version of TOMOYO is using its own function which doesn't append 582 * " (deleted)" suffix if the file is already unlink()ed; so that we don't 583 * need to worry whether the file is already unlink()ed or not. 584 */ 585LIST_HEAD(tomoyo_no_rewrite_list); 586 587/** 588 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. 589 * 590 * @pattern: Pathname pattern that are not rewritable by default. 591 * @is_delete: True if it is a delete request. 592 * 593 * Returns 0 on success, negative value otherwise. 594 * 595 * Caller holds tomoyo_read_lock(). 596 */ 597static int tomoyo_update_no_rewrite_entry(const char *pattern, 598 const bool is_delete) 599{ 600 struct tomoyo_no_rewrite_entry *ptr; 601 struct tomoyo_no_rewrite_entry e = { }; 602 int error = is_delete ? -ENOENT : -ENOMEM; 603 604 if (!tomoyo_is_correct_path(pattern, 0, 0, 0)) 605 return -EINVAL; 606 e.pattern = tomoyo_get_name(pattern); 607 if (!e.pattern) 608 return error; 609 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 610 goto out; 611 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 612 if (ptr->pattern != e.pattern) 613 continue; 614 ptr->is_deleted = is_delete; 615 error = 0; 616 break; 617 } 618 if (!is_delete && error) { 619 struct tomoyo_no_rewrite_entry *entry = 620 tomoyo_commit_ok(&e, sizeof(e)); 621 if (entry) { 622 list_add_tail_rcu(&entry->list, 623 &tomoyo_no_rewrite_list); 624 error = 0; 625 } 626 } 627 mutex_unlock(&tomoyo_policy_lock); 628 out: 629 tomoyo_put_name(e.pattern); 630 return error; 631} 632 633/** 634 * tomoyo_is_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. 635 * 636 * @filename: Filename to check. 637 * 638 * Returns true if @filename is specified by "deny_rewrite" directive, 639 * false otherwise. 640 * 641 * Caller holds tomoyo_read_lock(). 642 */ 643static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename) 644{ 645 struct tomoyo_no_rewrite_entry *ptr; 646 bool found = false; 647 648 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { 649 if (ptr->is_deleted) 650 continue; 651 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 652 continue; 653 found = true; 654 break; 655 } 656 return found; 657} 658 659/** 660 * tomoyo_write_no_rewrite_policy - Write "struct tomoyo_no_rewrite_entry" list. 661 * 662 * @data: String to parse. 663 * @is_delete: True if it is a delete request. 664 * 665 * Returns 0 on success, negative value otherwise. 666 * 667 * Caller holds tomoyo_read_lock(). 668 */ 669int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 670{ 671 return tomoyo_update_no_rewrite_entry(data, is_delete); 672} 673 674/** 675 * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list. 676 * 677 * @head: Pointer to "struct tomoyo_io_buffer". 678 * 679 * Returns true on success, false otherwise. 680 * 681 * Caller holds tomoyo_read_lock(). 682 */ 683bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 684{ 685 struct list_head *pos; 686 bool done = true; 687 688 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { 689 struct tomoyo_no_rewrite_entry *ptr; 690 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 691 if (ptr->is_deleted) 692 continue; 693 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE 694 "%s\n", ptr->pattern->name); 695 if (!done) 696 break; 697 } 698 return done; 699} 700 701/** 702 * tomoyo_update_file_acl - Update file's read/write/execute ACL. 703 * 704 * @perm: Permission (between 1 to 7). 705 * @filename: Filename. 706 * @domain: Pointer to "struct tomoyo_domain_info". 707 * @is_delete: True if it is a delete request. 708 * 709 * Returns 0 on success, negative value otherwise. 710 * 711 * This is legacy support interface for older policy syntax. 712 * Current policy syntax uses "allow_read/write" instead of "6", 713 * "allow_read" instead of "4", "allow_write" instead of "2", 714 * "allow_execute" instead of "1". 715 * 716 * Caller holds tomoyo_read_lock(). 717 */ 718static int tomoyo_update_file_acl(u8 perm, const char *filename, 719 struct tomoyo_domain_info * const domain, 720 const bool is_delete) 721{ 722 if (perm > 7 || !perm) { 723 printk(KERN_DEBUG "%s: Invalid permission '%d %s'\n", 724 __func__, perm, filename); 725 return -EINVAL; 726 } 727 if (filename[0] != '@' && tomoyo_strendswith(filename, "/")) 728 /* 729 * Only 'allow_mkdir' and 'allow_rmdir' are valid for 730 * directory permissions. 731 */ 732 return 0; 733 if (perm & 4) 734 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain, 735 is_delete); 736 if (perm & 2) 737 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain, 738 is_delete); 739 if (perm & 1) 740 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain, 741 is_delete); 742 return 0; 743} 744 745/** 746 * tomoyo_path_acl - Check permission for single path operation. 747 * 748 * @r: Pointer to "struct tomoyo_request_info". 749 * @filename: Filename to check. 750 * @perm: Permission. 751 * @may_use_pattern: True if patterned ACL is permitted. 752 * 753 * Returns 0 on success, -EPERM otherwise. 754 * 755 * Caller holds tomoyo_read_lock(). 756 */ 757static int tomoyo_path_acl(const struct tomoyo_request_info *r, 758 const struct tomoyo_path_info *filename, 759 const u32 perm, const bool may_use_pattern) 760{ 761 struct tomoyo_domain_info *domain = r->domain; 762 struct tomoyo_acl_info *ptr; 763 int error = -EPERM; 764 765 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 766 struct tomoyo_path_acl *acl; 767 if (ptr->type != TOMOYO_TYPE_PATH_ACL) 768 continue; 769 acl = container_of(ptr, struct tomoyo_path_acl, head); 770 if (!(acl->perm & perm) || 771 !tomoyo_compare_name_union_pattern(filename, &acl->name, 772 may_use_pattern)) 773 continue; 774 error = 0; 775 break; 776 } 777 return error; 778} 779 780/** 781 * tomoyo_file_perm - Check permission for opening files. 782 * 783 * @r: Pointer to "struct tomoyo_request_info". 784 * @filename: Filename to check. 785 * @mode: Mode ("read" or "write" or "read/write" or "execute"). 786 * 787 * Returns 0 on success, negative value otherwise. 788 * 789 * Caller holds tomoyo_read_lock(). 790 */ 791static int tomoyo_file_perm(struct tomoyo_request_info *r, 792 const struct tomoyo_path_info *filename, 793 const u8 mode) 794{ 795 const char *msg = "<unknown>"; 796 int error = 0; 797 u32 perm = 0; 798 799 if (!filename) 800 return 0; 801 802 if (mode == 6) { 803 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE); 804 perm = 1 << TOMOYO_TYPE_READ_WRITE; 805 } else if (mode == 4) { 806 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ); 807 perm = 1 << TOMOYO_TYPE_READ; 808 } else if (mode == 2) { 809 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE); 810 perm = 1 << TOMOYO_TYPE_WRITE; 811 } else if (mode == 1) { 812 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE); 813 perm = 1 << TOMOYO_TYPE_EXECUTE; 814 } else 815 BUG(); 816 error = tomoyo_path_acl(r, filename, perm, mode != 1); 817 if (error && mode == 4 && !r->domain->ignore_global_allow_read 818 && tomoyo_is_globally_readable_file(filename)) 819 error = 0; 820 if (!error) 821 return 0; 822 tomoyo_warn_log(r, "%s %s", msg, filename->name); 823 if (r->mode == TOMOYO_CONFIG_ENFORCING) 824 return error; 825 if (tomoyo_domain_quota_is_ok(r)) { 826 /* Don't use patterns for execute permission. */ 827 const struct tomoyo_path_info *patterned_file = (mode != 1) ? 828 tomoyo_get_file_pattern(filename) : filename; 829 tomoyo_update_file_acl(mode, patterned_file->name, r->domain, 830 false); 831 } 832 return 0; 833} 834 835/** 836 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 837 * 838 * @type: Type of operation. 839 * @filename: Filename. 840 * @domain: Pointer to "struct tomoyo_domain_info". 841 * @is_delete: True if it is a delete request. 842 * 843 * Returns 0 on success, negative value otherwise. 844 * 845 * Caller holds tomoyo_read_lock(). 846 */ 847static int tomoyo_update_path_acl(const u8 type, const char *filename, 848 struct tomoyo_domain_info *const domain, 849 const bool is_delete) 850{ 851 static const u16 tomoyo_rw_mask = 852 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE); 853 const u16 perm = 1 << type; 854 struct tomoyo_acl_info *ptr; 855 struct tomoyo_path_acl e = { 856 .head.type = TOMOYO_TYPE_PATH_ACL, 857 .perm = perm 858 }; 859 int error = is_delete ? -ENOENT : -ENOMEM; 860 861 if (type == TOMOYO_TYPE_READ_WRITE) 862 e.perm |= tomoyo_rw_mask; 863 if (!domain) 864 return -EINVAL; 865 if (!tomoyo_parse_name_union(filename, &e.name)) 866 return -EINVAL; 867 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 868 goto out; 869 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 870 struct tomoyo_path_acl *acl = 871 container_of(ptr, struct tomoyo_path_acl, head); 872 if (!tomoyo_is_same_path_acl(acl, &e)) 873 continue; 874 if (is_delete) { 875 acl->perm &= ~perm; 876 if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask) 877 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE); 878 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))) 879 acl->perm &= ~tomoyo_rw_mask; 880 } else { 881 acl->perm |= perm; 882 if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask) 883 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE; 884 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)) 885 acl->perm |= tomoyo_rw_mask; 886 } 887 error = 0; 888 break; 889 } 890 if (!is_delete && error) { 891 struct tomoyo_path_acl *entry = 892 tomoyo_commit_ok(&e, sizeof(e)); 893 if (entry) { 894 list_add_tail_rcu(&entry->head.list, 895 &domain->acl_info_list); 896 error = 0; 897 } 898 } 899 mutex_unlock(&tomoyo_policy_lock); 900 out: 901 tomoyo_put_name_union(&e.name); 902 return error; 903} 904 905/** 906 * tomoyo_update_path_number3_acl - Update "struct tomoyo_path_number3_acl" list. 907 * 908 * @type: Type of operation. 909 * @filename: Filename. 910 * @mode: Create mode. 911 * @major: Device major number. 912 * @minor: Device minor number. 913 * @domain: Pointer to "struct tomoyo_domain_info". 914 * @is_delete: True if it is a delete request. 915 * 916 * Returns 0 on success, negative value otherwise. 917 */ 918static inline int tomoyo_update_path_number3_acl(const u8 type, 919 const char *filename, 920 char *mode, 921 char *major, char *minor, 922 struct tomoyo_domain_info * 923 const domain, 924 const bool is_delete) 925{ 926 const u8 perm = 1 << type; 927 struct tomoyo_acl_info *ptr; 928 struct tomoyo_path_number3_acl e = { 929 .head.type = TOMOYO_TYPE_PATH_NUMBER3_ACL, 930 .perm = perm 931 }; 932 int error = is_delete ? -ENOENT : -ENOMEM; 933 if (!tomoyo_parse_name_union(filename, &e.name) || 934 !tomoyo_parse_number_union(mode, &e.mode) || 935 !tomoyo_parse_number_union(major, &e.major) || 936 !tomoyo_parse_number_union(minor, &e.minor)) 937 goto out; 938 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 939 goto out; 940 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 941 struct tomoyo_path_number3_acl *acl = 942 container_of(ptr, struct tomoyo_path_number3_acl, head); 943 if (!tomoyo_is_same_path_number3_acl(acl, &e)) 944 continue; 945 if (is_delete) 946 acl->perm &= ~perm; 947 else 948 acl->perm |= perm; 949 error = 0; 950 break; 951 } 952 if (!is_delete && error) { 953 struct tomoyo_path_number3_acl *entry = 954 tomoyo_commit_ok(&e, sizeof(e)); 955 if (entry) { 956 list_add_tail_rcu(&entry->head.list, 957 &domain->acl_info_list); 958 error = 0; 959 } 960 } 961 mutex_unlock(&tomoyo_policy_lock); 962 out: 963 tomoyo_put_name_union(&e.name); 964 tomoyo_put_number_union(&e.mode); 965 tomoyo_put_number_union(&e.major); 966 tomoyo_put_number_union(&e.minor); 967 return error; 968} 969 970/** 971 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 972 * 973 * @type: Type of operation. 974 * @filename1: First filename. 975 * @filename2: Second filename. 976 * @domain: Pointer to "struct tomoyo_domain_info". 977 * @is_delete: True if it is a delete request. 978 * 979 * Returns 0 on success, negative value otherwise. 980 * 981 * Caller holds tomoyo_read_lock(). 982 */ 983static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 984 const char *filename2, 985 struct tomoyo_domain_info *const domain, 986 const bool is_delete) 987{ 988 const u8 perm = 1 << type; 989 struct tomoyo_path2_acl e = { 990 .head.type = TOMOYO_TYPE_PATH2_ACL, 991 .perm = perm 992 }; 993 struct tomoyo_acl_info *ptr; 994 int error = is_delete ? -ENOENT : -ENOMEM; 995 996 if (!domain) 997 return -EINVAL; 998 if (!tomoyo_parse_name_union(filename1, &e.name1) || 999 !tomoyo_parse_name_union(filename2, &e.name2)) 1000 goto out; 1001 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1002 goto out; 1003 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1004 struct tomoyo_path2_acl *acl = 1005 container_of(ptr, struct tomoyo_path2_acl, head); 1006 if (!tomoyo_is_same_path2_acl(acl, &e)) 1007 continue; 1008 if (is_delete) 1009 acl->perm &= ~perm; 1010 else 1011 acl->perm |= perm; 1012 error = 0; 1013 break; 1014 } 1015 if (!is_delete && error) { 1016 struct tomoyo_path2_acl *entry = 1017 tomoyo_commit_ok(&e, sizeof(e)); 1018 if (entry) { 1019 list_add_tail_rcu(&entry->head.list, 1020 &domain->acl_info_list); 1021 error = 0; 1022 } 1023 } 1024 mutex_unlock(&tomoyo_policy_lock); 1025 out: 1026 tomoyo_put_name_union(&e.name1); 1027 tomoyo_put_name_union(&e.name2); 1028 return error; 1029} 1030 1031/** 1032 * tomoyo_path_number3_acl - Check permission for path/number/number/number operation. 1033 * 1034 * @r: Pointer to "struct tomoyo_request_info". 1035 * @filename: Filename to check. 1036 * @perm: Permission. 1037 * @mode: Create mode. 1038 * @major: Device major number. 1039 * @minor: Device minor number. 1040 * 1041 * Returns 0 on success, -EPERM otherwise. 1042 * 1043 * Caller holds tomoyo_read_lock(). 1044 */ 1045static int tomoyo_path_number3_acl(struct tomoyo_request_info *r, 1046 const struct tomoyo_path_info *filename, 1047 const u16 perm, const unsigned int mode, 1048 const unsigned int major, 1049 const unsigned int minor) 1050{ 1051 struct tomoyo_domain_info *domain = r->domain; 1052 struct tomoyo_acl_info *ptr; 1053 int error = -EPERM; 1054 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1055 struct tomoyo_path_number3_acl *acl; 1056 if (ptr->type != TOMOYO_TYPE_PATH_NUMBER3_ACL) 1057 continue; 1058 acl = container_of(ptr, struct tomoyo_path_number3_acl, head); 1059 if (!tomoyo_compare_number_union(mode, &acl->mode)) 1060 continue; 1061 if (!tomoyo_compare_number_union(major, &acl->major)) 1062 continue; 1063 if (!tomoyo_compare_number_union(minor, &acl->minor)) 1064 continue; 1065 if (!(acl->perm & perm)) 1066 continue; 1067 if (!tomoyo_compare_name_union(filename, &acl->name)) 1068 continue; 1069 error = 0; 1070 break; 1071 } 1072 return error; 1073} 1074 1075/** 1076 * tomoyo_path2_acl - Check permission for double path operation. 1077 * 1078 * @r: Pointer to "struct tomoyo_request_info". 1079 * @type: Type of operation. 1080 * @filename1: First filename to check. 1081 * @filename2: Second filename to check. 1082 * 1083 * Returns 0 on success, -EPERM otherwise. 1084 * 1085 * Caller holds tomoyo_read_lock(). 1086 */ 1087static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type, 1088 const struct tomoyo_path_info *filename1, 1089 const struct tomoyo_path_info *filename2) 1090{ 1091 const struct tomoyo_domain_info *domain = r->domain; 1092 struct tomoyo_acl_info *ptr; 1093 const u8 perm = 1 << type; 1094 int error = -EPERM; 1095 1096 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1097 struct tomoyo_path2_acl *acl; 1098 if (ptr->type != TOMOYO_TYPE_PATH2_ACL) 1099 continue; 1100 acl = container_of(ptr, struct tomoyo_path2_acl, head); 1101 if (!(acl->perm & perm)) 1102 continue; 1103 if (!tomoyo_compare_name_union(filename1, &acl->name1)) 1104 continue; 1105 if (!tomoyo_compare_name_union(filename2, &acl->name2)) 1106 continue; 1107 error = 0; 1108 break; 1109 } 1110 return error; 1111} 1112 1113/** 1114 * tomoyo_path_permission - Check permission for single path operation. 1115 * 1116 * @r: Pointer to "struct tomoyo_request_info". 1117 * @operation: Type of operation. 1118 * @filename: Filename to check. 1119 * 1120 * Returns 0 on success, negative value otherwise. 1121 * 1122 * Caller holds tomoyo_read_lock(). 1123 */ 1124static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 1125 const struct tomoyo_path_info *filename) 1126{ 1127 int error; 1128 1129 next: 1130 error = tomoyo_path_acl(r, filename, 1 << operation, 1); 1131 if (!error) 1132 goto ok; 1133 tomoyo_warn_log(r, "%s %s", tomoyo_path2keyword(operation), 1134 filename->name); 1135 if (tomoyo_domain_quota_is_ok(r)) { 1136 const char *name = tomoyo_get_file_pattern(filename)->name; 1137 tomoyo_update_path_acl(operation, name, r->domain, false); 1138 } 1139 if (r->mode != TOMOYO_CONFIG_ENFORCING) 1140 error = 0; 1141 ok: 1142 /* 1143 * Since "allow_truncate" doesn't imply "allow_rewrite" permission, 1144 * we need to check "allow_rewrite" permission if the filename is 1145 * specified by "deny_rewrite" keyword. 1146 */ 1147 if (!error && operation == TOMOYO_TYPE_TRUNCATE && 1148 tomoyo_is_no_rewrite_file(filename)) { 1149 operation = TOMOYO_TYPE_REWRITE; 1150 goto next; 1151 } 1152 return error; 1153} 1154 1155/** 1156 * tomoyo_path_number_acl - Check permission for ioctl/chmod/chown/chgrp operation. 1157 * 1158 * @r: Pointer to "struct tomoyo_request_info". 1159 * @type: Operation. 1160 * @filename: Filename to check. 1161 * @number: Number. 1162 * 1163 * Returns 0 on success, -EPERM otherwise. 1164 * 1165 * Caller holds tomoyo_read_lock(). 1166 */ 1167static int tomoyo_path_number_acl(struct tomoyo_request_info *r, const u8 type, 1168 const struct tomoyo_path_info *filename, 1169 const unsigned long number) 1170{ 1171 struct tomoyo_domain_info *domain = r->domain; 1172 struct tomoyo_acl_info *ptr; 1173 const u8 perm = 1 << type; 1174 int error = -EPERM; 1175 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1176 struct tomoyo_path_number_acl *acl; 1177 if (ptr->type != TOMOYO_TYPE_PATH_NUMBER_ACL) 1178 continue; 1179 acl = container_of(ptr, struct tomoyo_path_number_acl, 1180 head); 1181 if (!(acl->perm & perm) || 1182 !tomoyo_compare_number_union(number, &acl->number) || 1183 !tomoyo_compare_name_union(filename, &acl->name)) 1184 continue; 1185 error = 0; 1186 break; 1187 } 1188 return error; 1189} 1190 1191/** 1192 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. 1193 * 1194 * @type: Type of operation. 1195 * @filename: Filename. 1196 * @number: Number. 1197 * @domain: Pointer to "struct tomoyo_domain_info". 1198 * @is_delete: True if it is a delete request. 1199 * 1200 * Returns 0 on success, negative value otherwise. 1201 */ 1202static inline int tomoyo_update_path_number_acl(const u8 type, 1203 const char *filename, 1204 char *number, 1205 struct tomoyo_domain_info * 1206 const domain, 1207 const bool is_delete) 1208{ 1209 const u8 perm = 1 << type; 1210 struct tomoyo_acl_info *ptr; 1211 struct tomoyo_path_number_acl e = { 1212 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 1213 .perm = perm 1214 }; 1215 int error = is_delete ? -ENOENT : -ENOMEM; 1216 if (!domain) 1217 return -EINVAL; 1218 if (!tomoyo_parse_name_union(filename, &e.name)) 1219 return -EINVAL; 1220 if (!tomoyo_parse_number_union(number, &e.number)) 1221 goto out; 1222 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1223 goto out; 1224 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1225 struct tomoyo_path_number_acl *acl = 1226 container_of(ptr, struct tomoyo_path_number_acl, head); 1227 if (!tomoyo_is_same_path_number_acl(acl, &e)) 1228 continue; 1229 if (is_delete) 1230 acl->perm &= ~perm; 1231 else 1232 acl->perm |= perm; 1233 error = 0; 1234 break; 1235 } 1236 if (!is_delete && error) { 1237 struct tomoyo_path_number_acl *entry = 1238 tomoyo_commit_ok(&e, sizeof(e)); 1239 if (entry) { 1240 list_add_tail_rcu(&entry->head.list, 1241 &domain->acl_info_list); 1242 error = 0; 1243 } 1244 } 1245 mutex_unlock(&tomoyo_policy_lock); 1246 out: 1247 tomoyo_put_name_union(&e.name); 1248 tomoyo_put_number_union(&e.number); 1249 return error; 1250} 1251 1252/** 1253 * tomoyo_path_number_perm2 - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp". 1254 * 1255 * @r: Pointer to "strct tomoyo_request_info". 1256 * @filename: Filename to check. 1257 * @number: Number. 1258 * 1259 * Returns 0 on success, negative value otherwise. 1260 * 1261 * Caller holds tomoyo_read_lock(). 1262 */ 1263static int tomoyo_path_number_perm2(struct tomoyo_request_info *r, 1264 const u8 type, 1265 const struct tomoyo_path_info *filename, 1266 const unsigned long number) 1267{ 1268 char buffer[64]; 1269 int error; 1270 u8 radix; 1271 1272 if (!filename) 1273 return 0; 1274 switch (type) { 1275 case TOMOYO_TYPE_CREATE: 1276 case TOMOYO_TYPE_MKDIR: 1277 case TOMOYO_TYPE_MKFIFO: 1278 case TOMOYO_TYPE_MKSOCK: 1279 case TOMOYO_TYPE_CHMOD: 1280 radix = TOMOYO_VALUE_TYPE_OCTAL; 1281 break; 1282 case TOMOYO_TYPE_IOCTL: 1283 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL; 1284 break; 1285 default: 1286 radix = TOMOYO_VALUE_TYPE_DECIMAL; 1287 break; 1288 } 1289 tomoyo_print_ulong(buffer, sizeof(buffer), number, radix); 1290 error = tomoyo_path_number_acl(r, type, filename, number); 1291 if (!error) 1292 return 0; 1293 tomoyo_warn_log(r, "%s %s %s", tomoyo_path_number2keyword(type), 1294 filename->name, buffer); 1295 if (tomoyo_domain_quota_is_ok(r)) 1296 tomoyo_update_path_number_acl(type, 1297 tomoyo_get_file_pattern(filename) 1298 ->name, buffer, r->domain, false); 1299 if (r->mode != TOMOYO_CONFIG_ENFORCING) 1300 error = 0; 1301 return error; 1302} 1303 1304/** 1305 * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp". 1306 * 1307 * @type: Type of operation. 1308 * @path: Pointer to "struct path". 1309 * @number: Number. 1310 * 1311 * Returns 0 on success, negative value otherwise. 1312 */ 1313int tomoyo_path_number_perm(const u8 type, struct path *path, 1314 unsigned long number) 1315{ 1316 struct tomoyo_request_info r; 1317 int error = -ENOMEM; 1318 struct tomoyo_path_info *buf; 1319 int idx; 1320 1321 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1322 !path->mnt || !path->dentry) 1323 return 0; 1324 idx = tomoyo_read_lock(); 1325 buf = tomoyo_get_path(path); 1326 if (!buf) 1327 goto out; 1328 if (type == TOMOYO_TYPE_MKDIR && !buf->is_dir) { 1329 /* 1330 * tomoyo_get_path() reserves space for appending "/." 1331 */ 1332 strcat((char *) buf->name, "/"); 1333 tomoyo_fill_path_info(buf); 1334 } 1335 error = tomoyo_path_number_perm2(&r, type, buf, number); 1336 out: 1337 kfree(buf); 1338 tomoyo_read_unlock(idx); 1339 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1340 error = 0; 1341 return error; 1342} 1343 1344/** 1345 * tomoyo_check_exec_perm - Check permission for "execute". 1346 * 1347 * @domain: Pointer to "struct tomoyo_domain_info". 1348 * @filename: Check permission for "execute". 1349 * 1350 * Returns 0 on success, negativevalue otherwise. 1351 * 1352 * Caller holds tomoyo_read_lock(). 1353 */ 1354int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1355 const struct tomoyo_path_info *filename) 1356{ 1357 struct tomoyo_request_info r; 1358 1359 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED) 1360 return 0; 1361 return tomoyo_file_perm(&r, filename, 1); 1362} 1363 1364/** 1365 * tomoyo_check_open_permission - Check permission for "read" and "write". 1366 * 1367 * @domain: Pointer to "struct tomoyo_domain_info". 1368 * @path: Pointer to "struct path". 1369 * @flag: Flags for open(). 1370 * 1371 * Returns 0 on success, negative value otherwise. 1372 */ 1373int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 1374 struct path *path, const int flag) 1375{ 1376 const u8 acc_mode = ACC_MODE(flag); 1377 int error = -ENOMEM; 1378 struct tomoyo_path_info *buf; 1379 struct tomoyo_request_info r; 1380 int idx; 1381 1382 if (tomoyo_init_request_info(&r, domain) == TOMOYO_CONFIG_DISABLED || 1383 !path->mnt) 1384 return 0; 1385 if (acc_mode == 0) 1386 return 0; 1387 if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)) 1388 /* 1389 * I don't check directories here because mkdir() and rmdir() 1390 * don't call me. 1391 */ 1392 return 0; 1393 idx = tomoyo_read_lock(); 1394 buf = tomoyo_get_path(path); 1395 if (!buf) 1396 goto out; 1397 error = 0; 1398 /* 1399 * If the filename is specified by "deny_rewrite" keyword, 1400 * we need to check "allow_rewrite" permission when the filename is not 1401 * opened for append mode or the filename is truncated at open time. 1402 */ 1403 if ((acc_mode & MAY_WRITE) && 1404 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1405 (tomoyo_is_no_rewrite_file(buf))) { 1406 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, buf); 1407 } 1408 if (!error) 1409 error = tomoyo_file_perm(&r, buf, acc_mode); 1410 if (!error && (flag & O_TRUNC)) 1411 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, buf); 1412 out: 1413 kfree(buf); 1414 tomoyo_read_unlock(idx); 1415 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1416 error = 0; 1417 return error; 1418} 1419 1420/** 1421 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot", "mount" and "unmount". 1422 * 1423 * @operation: Type of operation. 1424 * @path: Pointer to "struct path". 1425 * 1426 * Returns 0 on success, negative value otherwise. 1427 */ 1428int tomoyo_path_perm(const u8 operation, struct path *path) 1429{ 1430 int error = -ENOMEM; 1431 struct tomoyo_path_info *buf; 1432 struct tomoyo_request_info r; 1433 int idx; 1434 1435 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1436 !path->mnt) 1437 return 0; 1438 idx = tomoyo_read_lock(); 1439 buf = tomoyo_get_path(path); 1440 if (!buf) 1441 goto out; 1442 switch (operation) { 1443 case TOMOYO_TYPE_REWRITE: 1444 if (!tomoyo_is_no_rewrite_file(buf)) { 1445 error = 0; 1446 goto out; 1447 } 1448 break; 1449 case TOMOYO_TYPE_RMDIR: 1450 case TOMOYO_TYPE_CHROOT: 1451 if (!buf->is_dir) { 1452 /* 1453 * tomoyo_get_path() reserves space for appending "/." 1454 */ 1455 strcat((char *) buf->name, "/"); 1456 tomoyo_fill_path_info(buf); 1457 } 1458 } 1459 error = tomoyo_path_permission(&r, operation, buf); 1460 out: 1461 kfree(buf); 1462 tomoyo_read_unlock(idx); 1463 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1464 error = 0; 1465 return error; 1466} 1467 1468/** 1469 * tomoyo_path_number3_perm2 - Check permission for path/number/number/number operation. 1470 * 1471 * @r: Pointer to "struct tomoyo_request_info". 1472 * @operation: Type of operation. 1473 * @filename: Filename to check. 1474 * @mode: Create mode. 1475 * @dev: Device number. 1476 * 1477 * Returns 0 on success, negative value otherwise. 1478 * 1479 * Caller holds tomoyo_read_lock(). 1480 */ 1481static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r, 1482 const u8 operation, 1483 const struct tomoyo_path_info *filename, 1484 const unsigned int mode, 1485 const unsigned int dev) 1486{ 1487 int error; 1488 const unsigned int major = MAJOR(dev); 1489 const unsigned int minor = MINOR(dev); 1490 1491 error = tomoyo_path_number3_acl(r, filename, 1 << operation, mode, 1492 major, minor); 1493 if (!error) 1494 return 0; 1495 tomoyo_warn_log(r, "%s %s 0%o %u %u", 1496 tomoyo_path_number32keyword(operation), 1497 filename->name, mode, major, minor); 1498 if (tomoyo_domain_quota_is_ok(r)) { 1499 char mode_buf[64]; 1500 char major_buf[64]; 1501 char minor_buf[64]; 1502 memset(mode_buf, 0, sizeof(mode_buf)); 1503 memset(major_buf, 0, sizeof(major_buf)); 1504 memset(minor_buf, 0, sizeof(minor_buf)); 1505 snprintf(mode_buf, sizeof(mode_buf) - 1, "0%o", mode); 1506 snprintf(major_buf, sizeof(major_buf) - 1, "%u", major); 1507 snprintf(minor_buf, sizeof(minor_buf) - 1, "%u", minor); 1508 tomoyo_update_path_number3_acl(operation, 1509 tomoyo_get_file_pattern(filename) 1510 ->name, mode_buf, major_buf, 1511 minor_buf, r->domain, false); 1512 } 1513 if (r->mode != TOMOYO_CONFIG_ENFORCING) 1514 error = 0; 1515 return error; 1516} 1517 1518/** 1519 * tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar". 1520 * 1521 * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK) 1522 * @path: Pointer to "struct path". 1523 * @mode: Create mode. 1524 * @dev: Device number. 1525 * 1526 * Returns 0 on success, negative value otherwise. 1527 */ 1528int tomoyo_path_number3_perm(const u8 operation, struct path *path, 1529 const unsigned int mode, unsigned int dev) 1530{ 1531 struct tomoyo_request_info r; 1532 int error = -ENOMEM; 1533 struct tomoyo_path_info *buf; 1534 int idx; 1535 1536 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1537 !path->mnt) 1538 return 0; 1539 idx = tomoyo_read_lock(); 1540 error = -ENOMEM; 1541 buf = tomoyo_get_path(path); 1542 if (buf) { 1543 error = tomoyo_path_number3_perm2(&r, operation, buf, mode, 1544 new_decode_dev(dev)); 1545 kfree(buf); 1546 } 1547 tomoyo_read_unlock(idx); 1548 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1549 error = 0; 1550 return error; 1551} 1552 1553/** 1554 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root". 1555 * 1556 * @operation: Type of operation. 1557 * @path1: Pointer to "struct path". 1558 * @path2: Pointer to "struct path". 1559 * 1560 * Returns 0 on success, negative value otherwise. 1561 */ 1562int tomoyo_path2_perm(const u8 operation, struct path *path1, 1563 struct path *path2) 1564{ 1565 int error = -ENOMEM; 1566 struct tomoyo_path_info *buf1; 1567 struct tomoyo_path_info *buf2; 1568 struct tomoyo_request_info r; 1569 int idx; 1570 1571 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED || 1572 !path1->mnt || !path2->mnt) 1573 return 0; 1574 idx = tomoyo_read_lock(); 1575 buf1 = tomoyo_get_path(path1); 1576 buf2 = tomoyo_get_path(path2); 1577 if (!buf1 || !buf2) 1578 goto out; 1579 { 1580 struct dentry *dentry = path1->dentry; 1581 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { 1582 /* 1583 * tomoyo_get_path() reserves space for appending "/." 1584 */ 1585 if (!buf1->is_dir) { 1586 strcat((char *) buf1->name, "/"); 1587 tomoyo_fill_path_info(buf1); 1588 } 1589 if (!buf2->is_dir) { 1590 strcat((char *) buf2->name, "/"); 1591 tomoyo_fill_path_info(buf2); 1592 } 1593 } 1594 } 1595 error = tomoyo_path2_acl(&r, operation, buf1, buf2); 1596 if (!error) 1597 goto out; 1598 tomoyo_warn_log(&r, "%s %s %s", tomoyo_path22keyword(operation), 1599 buf1->name, buf2->name); 1600 if (tomoyo_domain_quota_is_ok(&r)) { 1601 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1602 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1603 tomoyo_update_path2_acl(operation, name1, name2, r.domain, 1604 false); 1605 } 1606 out: 1607 kfree(buf1); 1608 kfree(buf2); 1609 tomoyo_read_unlock(idx); 1610 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1611 error = 0; 1612 return error; 1613} 1614 1615/** 1616 * tomoyo_write_file_policy - Update file related list. 1617 * 1618 * @data: String to parse. 1619 * @domain: Pointer to "struct tomoyo_domain_info". 1620 * @is_delete: True if it is a delete request. 1621 * 1622 * Returns 0 on success, negative value otherwise. 1623 * 1624 * Caller holds tomoyo_read_lock(). 1625 */ 1626int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 1627 const bool is_delete) 1628{ 1629 char *w[5]; 1630 u8 type; 1631 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) 1632 return -EINVAL; 1633 if (strncmp(w[0], "allow_", 6)) { 1634 unsigned int perm; 1635 if (sscanf(w[0], "%u", &perm) == 1) 1636 return tomoyo_update_file_acl((u8) perm, w[1], domain, 1637 is_delete); 1638 goto out; 1639 } 1640 w[0] += 6; 1641 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { 1642 if (strcmp(w[0], tomoyo_path_keyword[type])) 1643 continue; 1644 return tomoyo_update_path_acl(type, w[1], domain, is_delete); 1645 } 1646 if (!w[2][0]) 1647 goto out; 1648 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { 1649 if (strcmp(w[0], tomoyo_path2_keyword[type])) 1650 continue; 1651 return tomoyo_update_path2_acl(type, w[1], w[2], domain, 1652 is_delete); 1653 } 1654 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) { 1655 if (strcmp(w[0], tomoyo_path_number_keyword[type])) 1656 continue; 1657 return tomoyo_update_path_number_acl(type, w[1], w[2], domain, 1658 is_delete); 1659 } 1660 if (!w[3][0] || !w[4][0]) 1661 goto out; 1662 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER3_OPERATION; type++) { 1663 if (strcmp(w[0], tomoyo_path_number3_keyword[type])) 1664 continue; 1665 return tomoyo_update_path_number3_acl(type, w[1], w[2], w[3], 1666 w[4], domain, is_delete); 1667 } 1668 out: 1669 return -EINVAL; 1670} 1671