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