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