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