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. */ 13 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. */ 28 const char *tomoyo_mkdev_keyword[TOMOYO_MAX_MKDEV_OPERATION] = { 29 [TOMOYO_TYPE_MKBLOCK] = "mkblock", 30 [TOMOYO_TYPE_MKCHAR] = "mkchar", 31 }; 32 33 /* Keyword array for operations with two pathnames. */ 34 const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = { 35 [TOMOYO_TYPE_LINK] = "link", 36 [TOMOYO_TYPE_RENAME] = "rename", 37 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root", 38 }; 39 40 /* Keyword array for operations with one pathname and one number. */ 41 const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 42 [TOMOYO_TYPE_CREATE] = "create", 43 [TOMOYO_TYPE_MKDIR] = "mkdir", 44 [TOMOYO_TYPE_MKFIFO] = "mkfifo", 45 [TOMOYO_TYPE_MKSOCK] = "mksock", 46 [TOMOYO_TYPE_IOCTL] = "ioctl", 47 [TOMOYO_TYPE_CHMOD] = "chmod", 48 [TOMOYO_TYPE_CHOWN] = "chown", 49 [TOMOYO_TYPE_CHGRP] = "chgrp", 50 }; 51 52 static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 53 [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN, 54 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 55 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 56 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, 57 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, 58 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, 59 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, 60 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, 61 [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE, 62 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, 63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 64 }; 65 66 static const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { 67 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, 68 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, 69 }; 70 71 static const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { 72 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, 73 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, 74 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, 75 }; 76 77 static const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 78 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, 79 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, 80 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO, 81 [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK, 82 [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL, 83 [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD, 84 [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN, 85 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, 86 }; 87 88 void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 89 { 90 if (!ptr) 91 return; 92 if (ptr->is_group) 93 tomoyo_put_group(ptr->group); 94 else 95 tomoyo_put_name(ptr->filename); 96 } 97 98 const struct tomoyo_path_info * 99 tomoyo_compare_name_union(const struct tomoyo_path_info *name, 100 const struct tomoyo_name_union *ptr) 101 { 102 if (ptr->is_group) 103 return tomoyo_path_matches_group(name, ptr->group); 104 if (tomoyo_path_matches_pattern(name, ptr->filename)) 105 return ptr->filename; 106 return NULL; 107 } 108 109 void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 110 { 111 if (ptr && ptr->is_group) 112 tomoyo_put_group(ptr->group); 113 } 114 115 bool tomoyo_compare_number_union(const unsigned long value, 116 const struct tomoyo_number_union *ptr) 117 { 118 if (ptr->is_group) 119 return tomoyo_number_matches_group(value, value, ptr->group); 120 return value >= ptr->values[0] && value <= ptr->values[1]; 121 } 122 123 static void tomoyo_add_slash(struct tomoyo_path_info *buf) 124 { 125 if (buf->is_dir) 126 return; 127 /* 128 * This is OK because tomoyo_encode() reserves space for appending "/". 129 */ 130 strcat((char *) buf->name, "/"); 131 tomoyo_fill_path_info(buf); 132 } 133 134 /** 135 * tomoyo_strendswith - Check whether the token ends with the given token. 136 * 137 * @name: The token to check. 138 * @tail: The token to find. 139 * 140 * Returns true if @name ends with @tail, false otherwise. 141 */ 142 static bool tomoyo_strendswith(const char *name, const char *tail) 143 { 144 int len; 145 146 if (!name || !tail) 147 return false; 148 len = strlen(name) - strlen(tail); 149 return len >= 0 && !strcmp(name + len, tail); 150 } 151 152 /** 153 * tomoyo_get_realpath - Get realpath. 154 * 155 * @buf: Pointer to "struct tomoyo_path_info". 156 * @path: Pointer to "struct path". 157 * 158 * Returns true on success, false otherwise. 159 */ 160 static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path) 161 { 162 buf->name = tomoyo_realpath_from_path(path); 163 if (buf->name) { 164 tomoyo_fill_path_info(buf); 165 return true; 166 } 167 return false; 168 } 169 170 /** 171 * tomoyo_audit_path_log - Audit path request log. 172 * 173 * @r: Pointer to "struct tomoyo_request_info". 174 * 175 * Returns 0 on success, negative value otherwise. 176 */ 177 static int tomoyo_audit_path_log(struct tomoyo_request_info *r) 178 { 179 const char *operation = tomoyo_path_keyword[r->param.path.operation]; 180 const struct tomoyo_path_info *filename = r->param.path.filename; 181 if (r->granted) 182 return 0; 183 tomoyo_warn_log(r, "%s %s", operation, filename->name); 184 return tomoyo_supervisor(r, "allow_%s %s\n", operation, 185 tomoyo_pattern(filename)); 186 } 187 188 /** 189 * tomoyo_audit_path2_log - Audit path/path request log. 190 * 191 * @r: Pointer to "struct tomoyo_request_info". 192 * 193 * Returns 0 on success, negative value otherwise. 194 */ 195 static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) 196 { 197 const char *operation = tomoyo_path2_keyword[r->param.path2.operation]; 198 const struct tomoyo_path_info *filename1 = r->param.path2.filename1; 199 const struct tomoyo_path_info *filename2 = r->param.path2.filename2; 200 if (r->granted) 201 return 0; 202 tomoyo_warn_log(r, "%s %s %s", operation, filename1->name, 203 filename2->name); 204 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 205 tomoyo_pattern(filename1), 206 tomoyo_pattern(filename2)); 207 } 208 209 /** 210 * tomoyo_audit_mkdev_log - Audit path/number/number/number request log. 211 * 212 * @r: Pointer to "struct tomoyo_request_info". 213 * 214 * Returns 0 on success, negative value otherwise. 215 */ 216 static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) 217 { 218 const char *operation = tomoyo_mkdev_keyword[r->param.mkdev.operation]; 219 const struct tomoyo_path_info *filename = r->param.mkdev.filename; 220 const unsigned int major = r->param.mkdev.major; 221 const unsigned int minor = r->param.mkdev.minor; 222 const unsigned int mode = r->param.mkdev.mode; 223 if (r->granted) 224 return 0; 225 tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode, 226 major, minor); 227 return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation, 228 tomoyo_pattern(filename), mode, major, minor); 229 } 230 231 /** 232 * tomoyo_audit_path_number_log - Audit path/number request log. 233 * 234 * @r: Pointer to "struct tomoyo_request_info". 235 * @error: Error code. 236 * 237 * Returns 0 on success, negative value otherwise. 238 */ 239 static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r) 240 { 241 const u8 type = r->param.path_number.operation; 242 u8 radix; 243 const struct tomoyo_path_info *filename = r->param.path_number.filename; 244 const char *operation = tomoyo_path_number_keyword[type]; 245 char buffer[64]; 246 if (r->granted) 247 return 0; 248 switch (type) { 249 case TOMOYO_TYPE_CREATE: 250 case TOMOYO_TYPE_MKDIR: 251 case TOMOYO_TYPE_MKFIFO: 252 case TOMOYO_TYPE_MKSOCK: 253 case TOMOYO_TYPE_CHMOD: 254 radix = TOMOYO_VALUE_TYPE_OCTAL; 255 break; 256 case TOMOYO_TYPE_IOCTL: 257 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL; 258 break; 259 default: 260 radix = TOMOYO_VALUE_TYPE_DECIMAL; 261 break; 262 } 263 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number, 264 radix); 265 tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); 266 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 267 tomoyo_pattern(filename), buffer); 268 } 269 270 static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, 271 const struct tomoyo_acl_head *b) 272 { 273 return container_of(a, struct tomoyo_readable_file, 274 head)->filename == 275 container_of(b, struct tomoyo_readable_file, 276 head)->filename; 277 } 278 279 /** 280 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_readable_file" list. 281 * 282 * @filename: Filename unconditionally permitted to open() for reading. 283 * @is_delete: True if it is a delete request. 284 * 285 * Returns 0 on success, negative value otherwise. 286 * 287 * Caller holds tomoyo_read_lock(). 288 */ 289 static int tomoyo_update_globally_readable_entry(const char *filename, 290 const bool is_delete) 291 { 292 struct tomoyo_readable_file e = { }; 293 int error; 294 295 if (!tomoyo_correct_word(filename)) 296 return -EINVAL; 297 e.filename = tomoyo_get_name(filename); 298 if (!e.filename) 299 return -ENOMEM; 300 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 301 &tomoyo_policy_list 302 [TOMOYO_ID_GLOBALLY_READABLE], 303 tomoyo_same_globally_readable); 304 tomoyo_put_name(e.filename); 305 return error; 306 } 307 308 /** 309 * tomoyo_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading. 310 * 311 * @filename: The filename to check. 312 * 313 * Returns true if any domain can open @filename for reading, false otherwise. 314 * 315 * Caller holds tomoyo_read_lock(). 316 */ 317 static bool tomoyo_globally_readable_file(const struct tomoyo_path_info * 318 filename) 319 { 320 struct tomoyo_readable_file *ptr; 321 bool found = false; 322 323 list_for_each_entry_rcu(ptr, &tomoyo_policy_list 324 [TOMOYO_ID_GLOBALLY_READABLE], head.list) { 325 if (!ptr->head.is_deleted && 326 tomoyo_path_matches_pattern(filename, ptr->filename)) { 327 found = true; 328 break; 329 } 330 } 331 return found; 332 } 333 334 /** 335 * tomoyo_write_globally_readable - Write "struct tomoyo_readable_file" list. 336 * 337 * @data: String to parse. 338 * @is_delete: True if it is a delete request. 339 * 340 * Returns 0 on success, negative value otherwise. 341 * 342 * Caller holds tomoyo_read_lock(). 343 */ 344 int tomoyo_write_globally_readable(char *data, const bool is_delete) 345 { 346 return tomoyo_update_globally_readable_entry(data, is_delete); 347 } 348 349 static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, 350 const struct tomoyo_acl_head *b) 351 { 352 return container_of(a, struct tomoyo_no_pattern, head)->pattern == 353 container_of(b, struct tomoyo_no_pattern, head)->pattern; 354 } 355 356 /** 357 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_no_pattern" list. 358 * 359 * @pattern: Pathname pattern. 360 * @is_delete: True if it is a delete request. 361 * 362 * Returns 0 on success, negative value otherwise. 363 * 364 * Caller holds tomoyo_read_lock(). 365 */ 366 static int tomoyo_update_file_pattern_entry(const char *pattern, 367 const bool is_delete) 368 { 369 struct tomoyo_no_pattern e = { }; 370 int error; 371 372 if (!tomoyo_correct_word(pattern)) 373 return -EINVAL; 374 e.pattern = tomoyo_get_name(pattern); 375 if (!e.pattern) 376 return -ENOMEM; 377 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 378 &tomoyo_policy_list[TOMOYO_ID_PATTERN], 379 tomoyo_same_pattern); 380 tomoyo_put_name(e.pattern); 381 return error; 382 } 383 384 /** 385 * tomoyo_pattern - Get patterned pathname. 386 * 387 * @filename: The filename to find patterned pathname. 388 * 389 * Returns pointer to pathname pattern if matched, @filename otherwise. 390 * 391 * Caller holds tomoyo_read_lock(). 392 */ 393 const char *tomoyo_pattern(const struct tomoyo_path_info *filename) 394 { 395 struct tomoyo_no_pattern *ptr; 396 const struct tomoyo_path_info *pattern = NULL; 397 398 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN], 399 head.list) { 400 if (ptr->head.is_deleted) 401 continue; 402 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 403 continue; 404 pattern = ptr->pattern; 405 if (tomoyo_strendswith(pattern->name, "/\\*")) { 406 /* Do nothing. Try to find the better match. */ 407 } else { 408 /* This would be the better match. Use this. */ 409 break; 410 } 411 } 412 if (pattern) 413 filename = pattern; 414 return filename->name; 415 } 416 417 /** 418 * tomoyo_write_pattern - Write "struct tomoyo_no_pattern" list. 419 * 420 * @data: String to parse. 421 * @is_delete: True if it is a delete request. 422 * 423 * Returns 0 on success, negative value otherwise. 424 * 425 * Caller holds tomoyo_read_lock(). 426 */ 427 int tomoyo_write_pattern(char *data, const bool is_delete) 428 { 429 return tomoyo_update_file_pattern_entry(data, is_delete); 430 } 431 432 static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, 433 const struct tomoyo_acl_head *b) 434 { 435 return container_of(a, struct tomoyo_no_rewrite, head)->pattern 436 == container_of(b, struct tomoyo_no_rewrite, head) 437 ->pattern; 438 } 439 440 /** 441 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite" list. 442 * 443 * @pattern: Pathname pattern that are not rewritable by default. 444 * @is_delete: True if it is a delete request. 445 * 446 * Returns 0 on success, negative value otherwise. 447 * 448 * Caller holds tomoyo_read_lock(). 449 */ 450 static int tomoyo_update_no_rewrite_entry(const char *pattern, 451 const bool is_delete) 452 { 453 struct tomoyo_no_rewrite e = { }; 454 int error; 455 456 if (!tomoyo_correct_word(pattern)) 457 return -EINVAL; 458 e.pattern = tomoyo_get_name(pattern); 459 if (!e.pattern) 460 return -ENOMEM; 461 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, 462 &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], 463 tomoyo_same_no_rewrite); 464 tomoyo_put_name(e.pattern); 465 return error; 466 } 467 468 /** 469 * tomoyo_no_rewrite_file - Check if the given pathname is not permitted to be rewrited. 470 * 471 * @filename: Filename to check. 472 * 473 * Returns true if @filename is specified by "deny_rewrite" directive, 474 * false otherwise. 475 * 476 * Caller holds tomoyo_read_lock(). 477 */ 478 static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename) 479 { 480 struct tomoyo_no_rewrite *ptr; 481 bool found = false; 482 483 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], 484 head.list) { 485 if (ptr->head.is_deleted) 486 continue; 487 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 488 continue; 489 found = true; 490 break; 491 } 492 return found; 493 } 494 495 /** 496 * tomoyo_write_no_rewrite - Write "struct tomoyo_no_rewrite" list. 497 * 498 * @data: String to parse. 499 * @is_delete: True if it is a delete request. 500 * 501 * Returns 0 on success, negative value otherwise. 502 * 503 * Caller holds tomoyo_read_lock(). 504 */ 505 int tomoyo_write_no_rewrite(char *data, const bool is_delete) 506 { 507 return tomoyo_update_no_rewrite_entry(data, is_delete); 508 } 509 510 static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 511 const struct tomoyo_acl_info *ptr) 512 { 513 const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), 514 head); 515 if (acl->perm & (1 << r->param.path.operation)) { 516 r->param.path.matched_path = 517 tomoyo_compare_name_union(r->param.path.filename, 518 &acl->name); 519 return r->param.path.matched_path != NULL; 520 } 521 return false; 522 } 523 524 static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, 525 const struct tomoyo_acl_info *ptr) 526 { 527 const struct tomoyo_path_number_acl *acl = 528 container_of(ptr, typeof(*acl), head); 529 return (acl->perm & (1 << r->param.path_number.operation)) && 530 tomoyo_compare_number_union(r->param.path_number.number, 531 &acl->number) && 532 tomoyo_compare_name_union(r->param.path_number.filename, 533 &acl->name); 534 } 535 536 static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, 537 const struct tomoyo_acl_info *ptr) 538 { 539 const struct tomoyo_path2_acl *acl = 540 container_of(ptr, typeof(*acl), head); 541 return (acl->perm & (1 << r->param.path2.operation)) && 542 tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1) 543 && tomoyo_compare_name_union(r->param.path2.filename2, 544 &acl->name2); 545 } 546 547 static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, 548 const struct tomoyo_acl_info *ptr) 549 { 550 const struct tomoyo_mkdev_acl *acl = 551 container_of(ptr, typeof(*acl), head); 552 return (acl->perm & (1 << r->param.mkdev.operation)) && 553 tomoyo_compare_number_union(r->param.mkdev.mode, 554 &acl->mode) && 555 tomoyo_compare_number_union(r->param.mkdev.major, 556 &acl->major) && 557 tomoyo_compare_number_union(r->param.mkdev.minor, 558 &acl->minor) && 559 tomoyo_compare_name_union(r->param.mkdev.filename, 560 &acl->name); 561 } 562 563 static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 564 const struct tomoyo_acl_info *b) 565 { 566 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head); 567 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head); 568 return tomoyo_same_acl_head(&p1->head, &p2->head) && 569 tomoyo_same_name_union(&p1->name, &p2->name); 570 } 571 572 static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, 573 struct tomoyo_acl_info *b, 574 const bool is_delete) 575 { 576 u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head) 577 ->perm; 578 u16 perm = *a_perm; 579 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; 580 if (is_delete) { 581 perm &= ~b_perm; 582 if ((perm & TOMOYO_RW_MASK) != TOMOYO_RW_MASK) 583 perm &= ~(1 << TOMOYO_TYPE_READ_WRITE); 584 else if (!(perm & (1 << TOMOYO_TYPE_READ_WRITE))) 585 perm &= ~TOMOYO_RW_MASK; 586 } else { 587 perm |= b_perm; 588 if ((perm & TOMOYO_RW_MASK) == TOMOYO_RW_MASK) 589 perm |= (1 << TOMOYO_TYPE_READ_WRITE); 590 else if (perm & (1 << TOMOYO_TYPE_READ_WRITE)) 591 perm |= TOMOYO_RW_MASK; 592 } 593 *a_perm = perm; 594 return !perm; 595 } 596 597 /** 598 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 599 * 600 * @type: Type of operation. 601 * @filename: Filename. 602 * @domain: Pointer to "struct tomoyo_domain_info". 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 */ 609 static int tomoyo_update_path_acl(const u8 type, const char *filename, 610 struct tomoyo_domain_info * const domain, 611 const bool is_delete) 612 { 613 struct tomoyo_path_acl e = { 614 .head.type = TOMOYO_TYPE_PATH_ACL, 615 .perm = 1 << type 616 }; 617 int error; 618 if (e.perm == (1 << TOMOYO_TYPE_READ_WRITE)) 619 e.perm |= TOMOYO_RW_MASK; 620 if (!tomoyo_parse_name_union(filename, &e.name)) 621 return -EINVAL; 622 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 623 tomoyo_same_path_acl, 624 tomoyo_merge_path_acl); 625 tomoyo_put_name_union(&e.name); 626 return error; 627 } 628 629 static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, 630 const struct tomoyo_acl_info *b) 631 { 632 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), 633 head); 634 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), 635 head); 636 return tomoyo_same_acl_head(&p1->head, &p2->head) 637 && tomoyo_same_name_union(&p1->name, &p2->name) 638 && tomoyo_same_number_union(&p1->mode, &p2->mode) 639 && tomoyo_same_number_union(&p1->major, &p2->major) 640 && tomoyo_same_number_union(&p1->minor, &p2->minor); 641 } 642 643 static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, 644 struct tomoyo_acl_info *b, 645 const bool is_delete) 646 { 647 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, 648 head)->perm; 649 u8 perm = *a_perm; 650 const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head) 651 ->perm; 652 if (is_delete) 653 perm &= ~b_perm; 654 else 655 perm |= b_perm; 656 *a_perm = perm; 657 return !perm; 658 } 659 660 /** 661 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list. 662 * 663 * @type: Type of operation. 664 * @filename: Filename. 665 * @mode: Create mode. 666 * @major: Device major number. 667 * @minor: Device minor number. 668 * @domain: Pointer to "struct tomoyo_domain_info". 669 * @is_delete: True if it is a delete request. 670 * 671 * Returns 0 on success, negative value otherwise. 672 * 673 * Caller holds tomoyo_read_lock(). 674 */ 675 static int tomoyo_update_mkdev_acl(const u8 type, const char *filename, 676 char *mode, char *major, char *minor, 677 struct tomoyo_domain_info * const 678 domain, const bool is_delete) 679 { 680 struct tomoyo_mkdev_acl e = { 681 .head.type = TOMOYO_TYPE_MKDEV_ACL, 682 .perm = 1 << type 683 }; 684 int error = is_delete ? -ENOENT : -ENOMEM; 685 if (!tomoyo_parse_name_union(filename, &e.name) || 686 !tomoyo_parse_number_union(mode, &e.mode) || 687 !tomoyo_parse_number_union(major, &e.major) || 688 !tomoyo_parse_number_union(minor, &e.minor)) 689 goto out; 690 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 691 tomoyo_same_mkdev_acl, 692 tomoyo_merge_mkdev_acl); 693 out: 694 tomoyo_put_name_union(&e.name); 695 tomoyo_put_number_union(&e.mode); 696 tomoyo_put_number_union(&e.major); 697 tomoyo_put_number_union(&e.minor); 698 return error; 699 } 700 701 static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, 702 const struct tomoyo_acl_info *b) 703 { 704 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head); 705 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head); 706 return tomoyo_same_acl_head(&p1->head, &p2->head) 707 && tomoyo_same_name_union(&p1->name1, &p2->name1) 708 && tomoyo_same_name_union(&p1->name2, &p2->name2); 709 } 710 711 static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, 712 struct tomoyo_acl_info *b, 713 const bool is_delete) 714 { 715 u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head) 716 ->perm; 717 u8 perm = *a_perm; 718 const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm; 719 if (is_delete) 720 perm &= ~b_perm; 721 else 722 perm |= b_perm; 723 *a_perm = perm; 724 return !perm; 725 } 726 727 /** 728 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 729 * 730 * @type: Type of operation. 731 * @filename1: First filename. 732 * @filename2: Second filename. 733 * @domain: Pointer to "struct tomoyo_domain_info". 734 * @is_delete: True if it is a delete request. 735 * 736 * Returns 0 on success, negative value otherwise. 737 * 738 * Caller holds tomoyo_read_lock(). 739 */ 740 static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 741 const char *filename2, 742 struct tomoyo_domain_info * const domain, 743 const bool is_delete) 744 { 745 struct tomoyo_path2_acl e = { 746 .head.type = TOMOYO_TYPE_PATH2_ACL, 747 .perm = 1 << type 748 }; 749 int error = is_delete ? -ENOENT : -ENOMEM; 750 if (!tomoyo_parse_name_union(filename1, &e.name1) || 751 !tomoyo_parse_name_union(filename2, &e.name2)) 752 goto out; 753 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 754 tomoyo_same_path2_acl, 755 tomoyo_merge_path2_acl); 756 out: 757 tomoyo_put_name_union(&e.name1); 758 tomoyo_put_name_union(&e.name2); 759 return error; 760 } 761 762 /** 763 * tomoyo_path_permission - Check permission for single path operation. 764 * 765 * @r: Pointer to "struct tomoyo_request_info". 766 * @operation: Type of operation. 767 * @filename: Filename to check. 768 * 769 * Returns 0 on success, negative value otherwise. 770 * 771 * Caller holds tomoyo_read_lock(). 772 */ 773 int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 774 const struct tomoyo_path_info *filename) 775 { 776 int error; 777 778 next: 779 r->type = tomoyo_p2mac[operation]; 780 r->mode = tomoyo_get_mode(r->profile, r->type); 781 if (r->mode == TOMOYO_CONFIG_DISABLED) 782 return 0; 783 r->param_type = TOMOYO_TYPE_PATH_ACL; 784 r->param.path.filename = filename; 785 r->param.path.operation = operation; 786 do { 787 tomoyo_check_acl(r, tomoyo_check_path_acl); 788 if (!r->granted && operation == TOMOYO_TYPE_READ && 789 !r->domain->ignore_global_allow_read && 790 tomoyo_globally_readable_file(filename)) 791 r->granted = true; 792 error = tomoyo_audit_path_log(r); 793 /* 794 * Do not retry for execute request, for alias may have 795 * changed. 796 */ 797 } while (error == TOMOYO_RETRY_REQUEST && 798 operation != TOMOYO_TYPE_EXECUTE); 799 /* 800 * Since "allow_truncate" doesn't imply "allow_rewrite" permission, 801 * we need to check "allow_rewrite" permission if the filename is 802 * specified by "deny_rewrite" keyword. 803 */ 804 if (!error && operation == TOMOYO_TYPE_TRUNCATE && 805 tomoyo_no_rewrite_file(filename)) { 806 operation = TOMOYO_TYPE_REWRITE; 807 goto next; 808 } 809 return error; 810 } 811 812 static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 813 const struct tomoyo_acl_info *b) 814 { 815 const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1), 816 head); 817 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2), 818 head); 819 return tomoyo_same_acl_head(&p1->head, &p2->head) 820 && tomoyo_same_name_union(&p1->name, &p2->name) 821 && tomoyo_same_number_union(&p1->number, &p2->number); 822 } 823 824 static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, 825 struct tomoyo_acl_info *b, 826 const bool is_delete) 827 { 828 u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl, 829 head)->perm; 830 u8 perm = *a_perm; 831 const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head) 832 ->perm; 833 if (is_delete) 834 perm &= ~b_perm; 835 else 836 perm |= b_perm; 837 *a_perm = perm; 838 return !perm; 839 } 840 841 /** 842 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. 843 * 844 * @type: Type of operation. 845 * @filename: Filename. 846 * @number: Number. 847 * @domain: Pointer to "struct tomoyo_domain_info". 848 * @is_delete: True if it is a delete request. 849 * 850 * Returns 0 on success, negative value otherwise. 851 */ 852 static int tomoyo_update_path_number_acl(const u8 type, const char *filename, 853 char *number, 854 struct tomoyo_domain_info * const 855 domain, 856 const bool is_delete) 857 { 858 struct tomoyo_path_number_acl e = { 859 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 860 .perm = 1 << type 861 }; 862 int error = is_delete ? -ENOENT : -ENOMEM; 863 if (!tomoyo_parse_name_union(filename, &e.name)) 864 return -EINVAL; 865 if (!tomoyo_parse_number_union(number, &e.number)) 866 goto out; 867 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 868 tomoyo_same_path_number_acl, 869 tomoyo_merge_path_number_acl); 870 out: 871 tomoyo_put_name_union(&e.name); 872 tomoyo_put_number_union(&e.number); 873 return error; 874 } 875 876 /** 877 * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp". 878 * 879 * @type: Type of operation. 880 * @path: Pointer to "struct path". 881 * @number: Number. 882 * 883 * Returns 0 on success, negative value otherwise. 884 */ 885 int tomoyo_path_number_perm(const u8 type, struct path *path, 886 unsigned long number) 887 { 888 struct tomoyo_request_info r; 889 int error = -ENOMEM; 890 struct tomoyo_path_info buf; 891 int idx; 892 893 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) 894 == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry) 895 return 0; 896 idx = tomoyo_read_lock(); 897 if (!tomoyo_get_realpath(&buf, path)) 898 goto out; 899 if (type == TOMOYO_TYPE_MKDIR) 900 tomoyo_add_slash(&buf); 901 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; 902 r.param.path_number.operation = type; 903 r.param.path_number.filename = &buf; 904 r.param.path_number.number = number; 905 do { 906 tomoyo_check_acl(&r, tomoyo_check_path_number_acl); 907 error = tomoyo_audit_path_number_log(&r); 908 } while (error == TOMOYO_RETRY_REQUEST); 909 kfree(buf.name); 910 out: 911 tomoyo_read_unlock(idx); 912 if (r.mode != TOMOYO_CONFIG_ENFORCING) 913 error = 0; 914 return error; 915 } 916 917 /** 918 * tomoyo_check_open_permission - Check permission for "read" and "write". 919 * 920 * @domain: Pointer to "struct tomoyo_domain_info". 921 * @path: Pointer to "struct path". 922 * @flag: Flags for open(). 923 * 924 * Returns 0 on success, negative value otherwise. 925 */ 926 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 927 struct path *path, const int flag) 928 { 929 const u8 acc_mode = ACC_MODE(flag); 930 int error = 0; 931 struct tomoyo_path_info buf; 932 struct tomoyo_request_info r; 933 int idx; 934 935 if (!path->mnt || 936 (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))) 937 return 0; 938 buf.name = NULL; 939 r.mode = TOMOYO_CONFIG_DISABLED; 940 idx = tomoyo_read_lock(); 941 /* 942 * If the filename is specified by "deny_rewrite" keyword, 943 * we need to check "allow_rewrite" permission when the filename is not 944 * opened for append mode or the filename is truncated at open time. 945 */ 946 if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND) 947 && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE) 948 != TOMOYO_CONFIG_DISABLED) { 949 if (!tomoyo_get_realpath(&buf, path)) { 950 error = -ENOMEM; 951 goto out; 952 } 953 if (tomoyo_no_rewrite_file(&buf)) 954 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, 955 &buf); 956 } 957 if (!error && acc_mode && 958 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN) 959 != TOMOYO_CONFIG_DISABLED) { 960 u8 operation; 961 if (!buf.name && !tomoyo_get_realpath(&buf, path)) { 962 error = -ENOMEM; 963 goto out; 964 } 965 if (acc_mode == (MAY_READ | MAY_WRITE)) 966 operation = TOMOYO_TYPE_READ_WRITE; 967 else if (acc_mode == MAY_READ) 968 operation = TOMOYO_TYPE_READ; 969 else 970 operation = TOMOYO_TYPE_WRITE; 971 error = tomoyo_path_permission(&r, operation, &buf); 972 } 973 out: 974 kfree(buf.name); 975 tomoyo_read_unlock(idx); 976 if (r.mode != TOMOYO_CONFIG_ENFORCING) 977 error = 0; 978 return error; 979 } 980 981 /** 982 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount". 983 * 984 * @operation: Type of operation. 985 * @path: Pointer to "struct path". 986 * 987 * Returns 0 on success, negative value otherwise. 988 */ 989 int tomoyo_path_perm(const u8 operation, struct path *path) 990 { 991 int error = -ENOMEM; 992 struct tomoyo_path_info buf; 993 struct tomoyo_request_info r; 994 int idx; 995 996 if (!path->mnt) 997 return 0; 998 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) 999 == TOMOYO_CONFIG_DISABLED) 1000 return 0; 1001 buf.name = NULL; 1002 idx = tomoyo_read_lock(); 1003 if (!tomoyo_get_realpath(&buf, path)) 1004 goto out; 1005 switch (operation) { 1006 case TOMOYO_TYPE_REWRITE: 1007 if (!tomoyo_no_rewrite_file(&buf)) { 1008 error = 0; 1009 goto out; 1010 } 1011 break; 1012 case TOMOYO_TYPE_RMDIR: 1013 case TOMOYO_TYPE_CHROOT: 1014 tomoyo_add_slash(&buf); 1015 break; 1016 } 1017 error = tomoyo_path_permission(&r, operation, &buf); 1018 out: 1019 kfree(buf.name); 1020 tomoyo_read_unlock(idx); 1021 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1022 error = 0; 1023 return error; 1024 } 1025 1026 /** 1027 * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar". 1028 * 1029 * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK) 1030 * @path: Pointer to "struct path". 1031 * @mode: Create mode. 1032 * @dev: Device number. 1033 * 1034 * Returns 0 on success, negative value otherwise. 1035 */ 1036 int tomoyo_mkdev_perm(const u8 operation, struct path *path, 1037 const unsigned int mode, unsigned int dev) 1038 { 1039 struct tomoyo_request_info r; 1040 int error = -ENOMEM; 1041 struct tomoyo_path_info buf; 1042 int idx; 1043 1044 if (!path->mnt || 1045 tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation]) 1046 == TOMOYO_CONFIG_DISABLED) 1047 return 0; 1048 idx = tomoyo_read_lock(); 1049 error = -ENOMEM; 1050 if (tomoyo_get_realpath(&buf, path)) { 1051 dev = new_decode_dev(dev); 1052 r.param_type = TOMOYO_TYPE_MKDEV_ACL; 1053 r.param.mkdev.filename = &buf; 1054 r.param.mkdev.operation = operation; 1055 r.param.mkdev.mode = mode; 1056 r.param.mkdev.major = MAJOR(dev); 1057 r.param.mkdev.minor = MINOR(dev); 1058 tomoyo_check_acl(&r, tomoyo_check_mkdev_acl); 1059 error = tomoyo_audit_mkdev_log(&r); 1060 kfree(buf.name); 1061 } 1062 tomoyo_read_unlock(idx); 1063 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1064 error = 0; 1065 return error; 1066 } 1067 1068 /** 1069 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root". 1070 * 1071 * @operation: Type of operation. 1072 * @path1: Pointer to "struct path". 1073 * @path2: Pointer to "struct path". 1074 * 1075 * Returns 0 on success, negative value otherwise. 1076 */ 1077 int tomoyo_path2_perm(const u8 operation, struct path *path1, 1078 struct path *path2) 1079 { 1080 int error = -ENOMEM; 1081 struct tomoyo_path_info buf1; 1082 struct tomoyo_path_info buf2; 1083 struct tomoyo_request_info r; 1084 int idx; 1085 1086 if (!path1->mnt || !path2->mnt || 1087 tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation]) 1088 == TOMOYO_CONFIG_DISABLED) 1089 return 0; 1090 buf1.name = NULL; 1091 buf2.name = NULL; 1092 idx = tomoyo_read_lock(); 1093 if (!tomoyo_get_realpath(&buf1, path1) || 1094 !tomoyo_get_realpath(&buf2, path2)) 1095 goto out; 1096 switch (operation) { 1097 struct dentry *dentry; 1098 case TOMOYO_TYPE_RENAME: 1099 case TOMOYO_TYPE_LINK: 1100 dentry = path1->dentry; 1101 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) 1102 break; 1103 /* fall through */ 1104 case TOMOYO_TYPE_PIVOT_ROOT: 1105 tomoyo_add_slash(&buf1); 1106 tomoyo_add_slash(&buf2); 1107 break; 1108 } 1109 r.param_type = TOMOYO_TYPE_PATH2_ACL; 1110 r.param.path2.operation = operation; 1111 r.param.path2.filename1 = &buf1; 1112 r.param.path2.filename2 = &buf2; 1113 do { 1114 tomoyo_check_acl(&r, tomoyo_check_path2_acl); 1115 error = tomoyo_audit_path2_log(&r); 1116 } while (error == TOMOYO_RETRY_REQUEST); 1117 out: 1118 kfree(buf1.name); 1119 kfree(buf2.name); 1120 tomoyo_read_unlock(idx); 1121 if (r.mode != TOMOYO_CONFIG_ENFORCING) 1122 error = 0; 1123 return error; 1124 } 1125 1126 /** 1127 * tomoyo_write_file - Update file related list. 1128 * 1129 * @data: String to parse. 1130 * @domain: Pointer to "struct tomoyo_domain_info". 1131 * @is_delete: True if it is a delete request. 1132 * 1133 * Returns 0 on success, negative value otherwise. 1134 * 1135 * Caller holds tomoyo_read_lock(). 1136 */ 1137 int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain, 1138 const bool is_delete) 1139 { 1140 char *w[5]; 1141 u8 type; 1142 if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0]) 1143 return -EINVAL; 1144 if (strncmp(w[0], "allow_", 6)) 1145 goto out; 1146 w[0] += 6; 1147 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) { 1148 if (strcmp(w[0], tomoyo_path_keyword[type])) 1149 continue; 1150 return tomoyo_update_path_acl(type, w[1], domain, is_delete); 1151 } 1152 if (!w[2][0]) 1153 goto out; 1154 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) { 1155 if (strcmp(w[0], tomoyo_path2_keyword[type])) 1156 continue; 1157 return tomoyo_update_path2_acl(type, w[1], w[2], domain, 1158 is_delete); 1159 } 1160 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) { 1161 if (strcmp(w[0], tomoyo_path_number_keyword[type])) 1162 continue; 1163 return tomoyo_update_path_number_acl(type, w[1], w[2], domain, 1164 is_delete); 1165 } 1166 if (!w[3][0] || !w[4][0]) 1167 goto out; 1168 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++) { 1169 if (strcmp(w[0], tomoyo_mkdev_keyword[type])) 1170 continue; 1171 return tomoyo_update_mkdev_acl(type, w[1], w[2], w[3], 1172 w[4], domain, is_delete); 1173 } 1174 out: 1175 return -EINVAL; 1176 } 1177