common.c revision e5a3b95f581da62e2054ef79d3be2d383e9ed664
1/* 2 * security/tomoyo/common.c 3 * 4 * Common functions for TOMOYO. 5 * 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 7 * 8 * Version: 2.2.0-pre 2009/02/01 9 * 10 */ 11 12#include <linux/uaccess.h> 13#include <linux/security.h> 14#include <linux/hardirq.h> 15#include "realpath.h" 16#include "common.h" 17#include "tomoyo.h" 18 19/* Has loading policy done? */ 20bool tomoyo_policy_loaded; 21 22/* String table for functionality that takes 4 modes. */ 23static const char *tomoyo_mode_4[4] = { 24 "disabled", "learning", "permissive", "enforcing" 25}; 26/* String table for functionality that takes 2 modes. */ 27static const char *tomoyo_mode_2[4] = { 28 "disabled", "enabled", "enabled", "enabled" 29}; 30 31/* Table for profile. */ 32static struct { 33 const char *keyword; 34 unsigned int current_value; 35 const unsigned int max_value; 36} tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = { 37 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 }, 38 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX }, 39 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 40}; 41 42/* Profile table. Memory is allocated as needed. */ 43static struct tomoyo_profile { 44 unsigned int value[TOMOYO_MAX_CONTROL_INDEX]; 45 const struct tomoyo_path_info *comment; 46} *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; 47 48/* Permit policy management by non-root user? */ 49static bool tomoyo_manage_by_non_root; 50 51/* Utility functions. */ 52 53/* Open operation for /sys/kernel/security/tomoyo/ interface. */ 54static int tomoyo_open_control(const u8 type, struct file *file); 55/* Close /sys/kernel/security/tomoyo/ interface. */ 56static int tomoyo_close_control(struct file *file); 57/* Read operation for /sys/kernel/security/tomoyo/ interface. */ 58static int tomoyo_read_control(struct file *file, char __user *buffer, 59 const int buffer_len); 60/* Write operation for /sys/kernel/security/tomoyo/ interface. */ 61static int tomoyo_write_control(struct file *file, const char __user *buffer, 62 const int buffer_len); 63 64/** 65 * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. 66 * 67 * @str: Pointer to the string. 68 * 69 * Returns true if @str is a \ooo style octal value, false otherwise. 70 * 71 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF. 72 * This function verifies that \ooo is in valid range. 73 */ 74static inline bool tomoyo_is_byte_range(const char *str) 75{ 76 return *str >= '0' && *str++ <= '3' && 77 *str >= '0' && *str++ <= '7' && 78 *str >= '0' && *str <= '7'; 79} 80 81/** 82 * tomoyo_is_alphabet_char - Check whether the character is an alphabet. 83 * 84 * @c: The character to check. 85 * 86 * Returns true if @c is an alphabet character, false otherwise. 87 */ 88static inline bool tomoyo_is_alphabet_char(const char c) 89{ 90 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); 91} 92 93/** 94 * tomoyo_make_byte - Make byte value from three octal characters. 95 * 96 * @c1: The first character. 97 * @c2: The second character. 98 * @c3: The third character. 99 * 100 * Returns byte value. 101 */ 102static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3) 103{ 104 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0'); 105} 106 107/** 108 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 109 * 110 * @src: Pointer to pointer to the string. 111 * @find: Pointer to the keyword. 112 * 113 * Returns true if @src starts with @find, false otherwise. 114 * 115 * The @src is updated to point the first character after the @find 116 * if @src starts with @find. 117 */ 118static bool tomoyo_str_starts(char **src, const char *find) 119{ 120 const int len = strlen(find); 121 char *tmp = *src; 122 123 if (strncmp(tmp, find, len)) 124 return false; 125 tmp += len; 126 *src = tmp; 127 return true; 128} 129 130/** 131 * tomoyo_normalize_line - Format string. 132 * 133 * @buffer: The line to normalize. 134 * 135 * Leading and trailing whitespaces are removed. 136 * Multiple whitespaces are packed into single space. 137 * 138 * Returns nothing. 139 */ 140static void tomoyo_normalize_line(unsigned char *buffer) 141{ 142 unsigned char *sp = buffer; 143 unsigned char *dp = buffer; 144 bool first = true; 145 146 while (tomoyo_is_invalid(*sp)) 147 sp++; 148 while (*sp) { 149 if (!first) 150 *dp++ = ' '; 151 first = false; 152 while (tomoyo_is_valid(*sp)) 153 *dp++ = *sp++; 154 while (tomoyo_is_invalid(*sp)) 155 sp++; 156 } 157 *dp = '\0'; 158} 159 160/** 161 * tomoyo_is_correct_path - Validate a pathname. 162 * @filename: The pathname to check. 163 * @start_type: Should the pathname start with '/'? 164 * 1 = must / -1 = must not / 0 = don't care 165 * @pattern_type: Can the pathname contain a wildcard? 166 * 1 = must / -1 = must not / 0 = don't care 167 * @end_type: Should the pathname end with '/'? 168 * 1 = must / -1 = must not / 0 = don't care 169 * @function: The name of function calling me. 170 * 171 * Check whether the given filename follows the naming rules. 172 * Returns true if @filename follows the naming rules, false otherwise. 173 */ 174bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 175 const s8 pattern_type, const s8 end_type, 176 const char *function) 177{ 178 bool contains_pattern = false; 179 unsigned char c; 180 unsigned char d; 181 unsigned char e; 182 const char *original_filename = filename; 183 184 if (!filename) 185 goto out; 186 c = *filename; 187 if (start_type == 1) { /* Must start with '/' */ 188 if (c != '/') 189 goto out; 190 } else if (start_type == -1) { /* Must not start with '/' */ 191 if (c == '/') 192 goto out; 193 } 194 if (c) 195 c = *(filename + strlen(filename) - 1); 196 if (end_type == 1) { /* Must end with '/' */ 197 if (c != '/') 198 goto out; 199 } else if (end_type == -1) { /* Must not end with '/' */ 200 if (c == '/') 201 goto out; 202 } 203 while ((c = *filename++) != '\0') { 204 if (c == '\\') { 205 switch ((c = *filename++)) { 206 case '\\': /* "\\" */ 207 continue; 208 case '$': /* "\$" */ 209 case '+': /* "\+" */ 210 case '?': /* "\?" */ 211 case '*': /* "\*" */ 212 case '@': /* "\@" */ 213 case 'x': /* "\x" */ 214 case 'X': /* "\X" */ 215 case 'a': /* "\a" */ 216 case 'A': /* "\A" */ 217 case '-': /* "\-" */ 218 if (pattern_type == -1) 219 break; /* Must not contain pattern */ 220 contains_pattern = true; 221 continue; 222 case '0': /* "\ooo" */ 223 case '1': 224 case '2': 225 case '3': 226 d = *filename++; 227 if (d < '0' || d > '7') 228 break; 229 e = *filename++; 230 if (e < '0' || e > '7') 231 break; 232 c = tomoyo_make_byte(c, d, e); 233 if (tomoyo_is_invalid(c)) 234 continue; /* pattern is not \000 */ 235 } 236 goto out; 237 } else if (tomoyo_is_invalid(c)) { 238 goto out; 239 } 240 } 241 if (pattern_type == 1) { /* Must contain pattern */ 242 if (!contains_pattern) 243 goto out; 244 } 245 return true; 246 out: 247 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, 248 original_filename); 249 return false; 250} 251 252/** 253 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules. 254 * @domainname: The domainname to check. 255 * @function: The name of function calling me. 256 * 257 * Returns true if @domainname follows the naming rules, false otherwise. 258 */ 259bool tomoyo_is_correct_domain(const unsigned char *domainname, 260 const char *function) 261{ 262 unsigned char c; 263 unsigned char d; 264 unsigned char e; 265 const char *org_domainname = domainname; 266 267 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 268 TOMOYO_ROOT_NAME_LEN)) 269 goto out; 270 domainname += TOMOYO_ROOT_NAME_LEN; 271 if (!*domainname) 272 return true; 273 do { 274 if (*domainname++ != ' ') 275 goto out; 276 if (*domainname++ != '/') 277 goto out; 278 while ((c = *domainname) != '\0' && c != ' ') { 279 domainname++; 280 if (c == '\\') { 281 c = *domainname++; 282 switch ((c)) { 283 case '\\': /* "\\" */ 284 continue; 285 case '0': /* "\ooo" */ 286 case '1': 287 case '2': 288 case '3': 289 d = *domainname++; 290 if (d < '0' || d > '7') 291 break; 292 e = *domainname++; 293 if (e < '0' || e > '7') 294 break; 295 c = tomoyo_make_byte(c, d, e); 296 if (tomoyo_is_invalid(c)) 297 /* pattern is not \000 */ 298 continue; 299 } 300 goto out; 301 } else if (tomoyo_is_invalid(c)) { 302 goto out; 303 } 304 } 305 } while (*domainname); 306 return true; 307 out: 308 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function, 309 org_domainname); 310 return false; 311} 312 313/** 314 * tomoyo_is_domain_def - Check whether the given token can be a domainname. 315 * 316 * @buffer: The token to check. 317 * 318 * Returns true if @buffer possibly be a domainname, false otherwise. 319 */ 320bool tomoyo_is_domain_def(const unsigned char *buffer) 321{ 322 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN); 323} 324 325/** 326 * tomoyo_find_domain - Find a domain by the given name. 327 * 328 * @domainname: The domainname to find. 329 * 330 * Caller must call down_read(&tomoyo_domain_list_lock); or 331 * down_write(&tomoyo_domain_list_lock); . 332 * 333 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. 334 */ 335struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 336{ 337 struct tomoyo_domain_info *domain; 338 struct tomoyo_path_info name; 339 340 name.name = domainname; 341 tomoyo_fill_path_info(&name); 342 list_for_each_entry(domain, &tomoyo_domain_list, list) { 343 if (!domain->is_deleted && 344 !tomoyo_pathcmp(&name, domain->domainname)) 345 return domain; 346 } 347 return NULL; 348} 349 350/** 351 * tomoyo_path_depth - Evaluate the number of '/' in a string. 352 * 353 * @pathname: The string to evaluate. 354 * 355 * Returns path depth of the string. 356 * 357 * I score 2 for each of the '/' in the @pathname 358 * and score 1 if the @pathname ends with '/'. 359 */ 360static int tomoyo_path_depth(const char *pathname) 361{ 362 int i = 0; 363 364 if (pathname) { 365 const char *ep = pathname + strlen(pathname); 366 if (pathname < ep--) { 367 if (*ep != '/') 368 i++; 369 while (pathname <= ep) 370 if (*ep-- == '/') 371 i += 2; 372 } 373 } 374 return i; 375} 376 377/** 378 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. 379 * 380 * @filename: The string to evaluate. 381 * 382 * Returns the initial length without a pattern in @filename. 383 */ 384static int tomoyo_const_part_length(const char *filename) 385{ 386 char c; 387 int len = 0; 388 389 if (!filename) 390 return 0; 391 while ((c = *filename++) != '\0') { 392 if (c != '\\') { 393 len++; 394 continue; 395 } 396 c = *filename++; 397 switch (c) { 398 case '\\': /* "\\" */ 399 len += 2; 400 continue; 401 case '0': /* "\ooo" */ 402 case '1': 403 case '2': 404 case '3': 405 c = *filename++; 406 if (c < '0' || c > '7') 407 break; 408 c = *filename++; 409 if (c < '0' || c > '7') 410 break; 411 len += 4; 412 continue; 413 } 414 break; 415 } 416 return len; 417} 418 419/** 420 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members. 421 * 422 * @ptr: Pointer to "struct tomoyo_path_info" to fill in. 423 * 424 * The caller sets "struct tomoyo_path_info"->name. 425 */ 426void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) 427{ 428 const char *name = ptr->name; 429 const int len = strlen(name); 430 431 ptr->total_len = len; 432 ptr->const_len = tomoyo_const_part_length(name); 433 ptr->is_dir = len && (name[len - 1] == '/'); 434 ptr->is_patterned = (ptr->const_len < len); 435 ptr->hash = full_name_hash(name, len); 436 ptr->depth = tomoyo_path_depth(name); 437} 438 439/** 440 * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character 441 * and "\-" pattern. 442 * 443 * @filename: The start of string to check. 444 * @filename_end: The end of string to check. 445 * @pattern: The start of pattern to compare. 446 * @pattern_end: The end of pattern to compare. 447 * 448 * Returns true if @filename matches @pattern, false otherwise. 449 */ 450static bool tomoyo_file_matches_to_pattern2(const char *filename, 451 const char *filename_end, 452 const char *pattern, 453 const char *pattern_end) 454{ 455 while (filename < filename_end && pattern < pattern_end) { 456 char c; 457 if (*pattern != '\\') { 458 if (*filename++ != *pattern++) 459 return false; 460 continue; 461 } 462 c = *filename; 463 pattern++; 464 switch (*pattern) { 465 int i; 466 int j; 467 case '?': 468 if (c == '/') { 469 return false; 470 } else if (c == '\\') { 471 if (filename[1] == '\\') 472 filename++; 473 else if (tomoyo_is_byte_range(filename + 1)) 474 filename += 3; 475 else 476 return false; 477 } 478 break; 479 case '\\': 480 if (c != '\\') 481 return false; 482 if (*++filename != '\\') 483 return false; 484 break; 485 case '+': 486 if (!isdigit(c)) 487 return false; 488 break; 489 case 'x': 490 if (!isxdigit(c)) 491 return false; 492 break; 493 case 'a': 494 if (!tomoyo_is_alphabet_char(c)) 495 return false; 496 break; 497 case '0': 498 case '1': 499 case '2': 500 case '3': 501 if (c == '\\' && tomoyo_is_byte_range(filename + 1) 502 && strncmp(filename + 1, pattern, 3) == 0) { 503 filename += 3; 504 pattern += 2; 505 break; 506 } 507 return false; /* Not matched. */ 508 case '*': 509 case '@': 510 for (i = 0; i <= filename_end - filename; i++) { 511 if (tomoyo_file_matches_to_pattern2( 512 filename + i, filename_end, 513 pattern + 1, pattern_end)) 514 return true; 515 c = filename[i]; 516 if (c == '.' && *pattern == '@') 517 break; 518 if (c != '\\') 519 continue; 520 if (filename[i + 1] == '\\') 521 i++; 522 else if (tomoyo_is_byte_range(filename + i + 1)) 523 i += 3; 524 else 525 break; /* Bad pattern. */ 526 } 527 return false; /* Not matched. */ 528 default: 529 j = 0; 530 c = *pattern; 531 if (c == '$') { 532 while (isdigit(filename[j])) 533 j++; 534 } else if (c == 'X') { 535 while (isxdigit(filename[j])) 536 j++; 537 } else if (c == 'A') { 538 while (tomoyo_is_alphabet_char(filename[j])) 539 j++; 540 } 541 for (i = 1; i <= j; i++) { 542 if (tomoyo_file_matches_to_pattern2( 543 filename + i, filename_end, 544 pattern + 1, pattern_end)) 545 return true; 546 } 547 return false; /* Not matched or bad pattern. */ 548 } 549 filename++; 550 pattern++; 551 } 552 while (*pattern == '\\' && 553 (*(pattern + 1) == '*' || *(pattern + 1) == '@')) 554 pattern += 2; 555 return filename == filename_end && pattern == pattern_end; 556} 557 558/** 559 * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character. 560 * 561 * @filename: The start of string to check. 562 * @filename_end: The end of string to check. 563 * @pattern: The start of pattern to compare. 564 * @pattern_end: The end of pattern to compare. 565 * 566 * Returns true if @filename matches @pattern, false otherwise. 567 */ 568static bool tomoyo_file_matches_to_pattern(const char *filename, 569 const char *filename_end, 570 const char *pattern, 571 const char *pattern_end) 572{ 573 const char *pattern_start = pattern; 574 bool first = true; 575 bool result; 576 577 while (pattern < pattern_end - 1) { 578 /* Split at "\-" pattern. */ 579 if (*pattern++ != '\\' || *pattern++ != '-') 580 continue; 581 result = tomoyo_file_matches_to_pattern2(filename, 582 filename_end, 583 pattern_start, 584 pattern - 2); 585 if (first) 586 result = !result; 587 if (result) 588 return false; 589 first = false; 590 pattern_start = pattern; 591 } 592 result = tomoyo_file_matches_to_pattern2(filename, filename_end, 593 pattern_start, pattern_end); 594 return first ? result : !result; 595} 596 597/** 598 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. 599 * @filename: The filename to check. 600 * @pattern: The pattern to compare. 601 * 602 * Returns true if matches, false otherwise. 603 * 604 * The following patterns are available. 605 * \\ \ itself. 606 * \ooo Octal representation of a byte. 607 * \* More than or equals to 0 character other than '/'. 608 * \@ More than or equals to 0 character other than '/' or '.'. 609 * \? 1 byte character other than '/'. 610 * \$ More than or equals to 1 decimal digit. 611 * \+ 1 decimal digit. 612 * \X More than or equals to 1 hexadecimal digit. 613 * \x 1 hexadecimal digit. 614 * \A More than or equals to 1 alphabet character. 615 * \a 1 alphabet character. 616 * \- Subtraction operator. 617 */ 618bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 619 const struct tomoyo_path_info *pattern) 620{ 621 /* 622 if (!filename || !pattern) 623 return false; 624 */ 625 const char *f = filename->name; 626 const char *p = pattern->name; 627 const int len = pattern->const_len; 628 629 /* If @pattern doesn't contain pattern, I can use strcmp(). */ 630 if (!pattern->is_patterned) 631 return !tomoyo_pathcmp(filename, pattern); 632 /* Dont compare if the number of '/' differs. */ 633 if (filename->depth != pattern->depth) 634 return false; 635 /* Compare the initial length without patterns. */ 636 if (strncmp(f, p, len)) 637 return false; 638 f += len; 639 p += len; 640 /* Main loop. Compare each directory component. */ 641 while (*f && *p) { 642 const char *f_delimiter = strchr(f, '/'); 643 const char *p_delimiter = strchr(p, '/'); 644 if (!f_delimiter) 645 f_delimiter = f + strlen(f); 646 if (!p_delimiter) 647 p_delimiter = p + strlen(p); 648 if (!tomoyo_file_matches_to_pattern(f, f_delimiter, 649 p, p_delimiter)) 650 return false; 651 f = f_delimiter; 652 if (*f) 653 f++; 654 p = p_delimiter; 655 if (*p) 656 p++; 657 } 658 /* Ignore trailing "\*" and "\@" in @pattern. */ 659 while (*p == '\\' && 660 (*(p + 1) == '*' || *(p + 1) == '@')) 661 p += 2; 662 return !*f && !*p; 663} 664 665/** 666 * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure. 667 * 668 * @head: Pointer to "struct tomoyo_io_buffer". 669 * @fmt: The printf()'s format string, followed by parameters. 670 * 671 * Returns true if output was written, false otherwise. 672 * 673 * The snprintf() will truncate, but tomoyo_io_printf() won't. 674 */ 675bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 676{ 677 va_list args; 678 int len; 679 int pos = head->read_avail; 680 int size = head->readbuf_size - pos; 681 682 if (size <= 0) 683 return false; 684 va_start(args, fmt); 685 len = vsnprintf(head->read_buf + pos, size, fmt, args); 686 va_end(args); 687 if (pos + len >= head->readbuf_size) 688 return false; 689 head->read_avail += len; 690 return true; 691} 692 693/** 694 * tomoyo_get_exe - Get tomoyo_realpath() of current process. 695 * 696 * Returns the tomoyo_realpath() of current process on success, NULL otherwise. 697 * 698 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free() 699 * if this function didn't return NULL. 700 */ 701static const char *tomoyo_get_exe(void) 702{ 703 struct mm_struct *mm = current->mm; 704 struct vm_area_struct *vma; 705 const char *cp = NULL; 706 707 if (!mm) 708 return NULL; 709 down_read(&mm->mmap_sem); 710 for (vma = mm->mmap; vma; vma = vma->vm_next) { 711 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { 712 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path); 713 break; 714 } 715 } 716 up_read(&mm->mmap_sem); 717 return cp; 718} 719 720/** 721 * tomoyo_get_msg - Get warning message. 722 * 723 * @is_enforce: Is it enforcing mode? 724 * 725 * Returns "ERROR" or "WARNING". 726 */ 727const char *tomoyo_get_msg(const bool is_enforce) 728{ 729 if (is_enforce) 730 return "ERROR"; 731 else 732 return "WARNING"; 733} 734 735/** 736 * tomoyo_check_flags - Check mode for specified functionality. 737 * 738 * @domain: Pointer to "struct tomoyo_domain_info". 739 * @index: The functionality to check mode. 740 * 741 * TOMOYO checks only process context. 742 * This code disables TOMOYO's enforcement in case the function is called from 743 * interrupt context. 744 */ 745unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 746 const u8 index) 747{ 748 const u8 profile = domain->profile; 749 750 if (WARN_ON(in_interrupt())) 751 return 0; 752 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX 753#if TOMOYO_MAX_PROFILES != 256 754 && profile < TOMOYO_MAX_PROFILES 755#endif 756 && tomoyo_profile_ptr[profile] ? 757 tomoyo_profile_ptr[profile]->value[index] : 0; 758} 759 760/** 761 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode. 762 * 763 * @domain: Pointer to "struct tomoyo_domain_info". 764 * 765 * Returns true if domain policy violation warning should be printed to 766 * console. 767 */ 768bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain) 769{ 770 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0; 771} 772 773/** 774 * tomoyo_domain_quota_is_ok - Check for domain's quota. 775 * 776 * @domain: Pointer to "struct tomoyo_domain_info". 777 * 778 * Returns true if the domain is not exceeded quota, false otherwise. 779 */ 780bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 781{ 782 unsigned int count = 0; 783 struct tomoyo_acl_info *ptr; 784 785 if (!domain) 786 return true; 787 down_read(&tomoyo_domain_acl_info_list_lock); 788 list_for_each_entry(ptr, &domain->acl_info_list, list) { 789 if (ptr->type & TOMOYO_ACL_DELETED) 790 continue; 791 switch (tomoyo_acl_type2(ptr)) { 792 struct tomoyo_single_path_acl_record *acl1; 793 struct tomoyo_double_path_acl_record *acl2; 794 u16 perm; 795 case TOMOYO_TYPE_SINGLE_PATH_ACL: 796 acl1 = container_of(ptr, 797 struct tomoyo_single_path_acl_record, 798 head); 799 perm = acl1->perm; 800 if (perm & (1 << TOMOYO_TYPE_EXECUTE_ACL)) 801 count++; 802 if (perm & 803 ((1 << TOMOYO_TYPE_READ_ACL) | 804 (1 << TOMOYO_TYPE_WRITE_ACL))) 805 count++; 806 if (perm & (1 << TOMOYO_TYPE_CREATE_ACL)) 807 count++; 808 if (perm & (1 << TOMOYO_TYPE_UNLINK_ACL)) 809 count++; 810 if (perm & (1 << TOMOYO_TYPE_MKDIR_ACL)) 811 count++; 812 if (perm & (1 << TOMOYO_TYPE_RMDIR_ACL)) 813 count++; 814 if (perm & (1 << TOMOYO_TYPE_MKFIFO_ACL)) 815 count++; 816 if (perm & (1 << TOMOYO_TYPE_MKSOCK_ACL)) 817 count++; 818 if (perm & (1 << TOMOYO_TYPE_MKBLOCK_ACL)) 819 count++; 820 if (perm & (1 << TOMOYO_TYPE_MKCHAR_ACL)) 821 count++; 822 if (perm & (1 << TOMOYO_TYPE_TRUNCATE_ACL)) 823 count++; 824 if (perm & (1 << TOMOYO_TYPE_SYMLINK_ACL)) 825 count++; 826 if (perm & (1 << TOMOYO_TYPE_REWRITE_ACL)) 827 count++; 828 break; 829 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 830 acl2 = container_of(ptr, 831 struct tomoyo_double_path_acl_record, 832 head); 833 perm = acl2->perm; 834 if (perm & (1 << TOMOYO_TYPE_LINK_ACL)) 835 count++; 836 if (perm & (1 << TOMOYO_TYPE_RENAME_ACL)) 837 count++; 838 break; 839 } 840 } 841 up_read(&tomoyo_domain_acl_info_list_lock); 842 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 843 return true; 844 if (!domain->quota_warned) { 845 domain->quota_warned = true; 846 printk(KERN_WARNING "TOMOYO-WARNING: " 847 "Domain '%s' has so many ACLs to hold. " 848 "Stopped learning mode.\n", domain->domainname->name); 849 } 850 return false; 851} 852 853/** 854 * tomoyo_find_or_assign_new_profile - Create a new profile. 855 * 856 * @profile: Profile number to create. 857 * 858 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 859 */ 860static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned 861 int profile) 862{ 863 static DEFINE_MUTEX(lock); 864 struct tomoyo_profile *ptr = NULL; 865 int i; 866 867 if (profile >= TOMOYO_MAX_PROFILES) 868 return NULL; 869 /***** EXCLUSIVE SECTION START *****/ 870 mutex_lock(&lock); 871 ptr = tomoyo_profile_ptr[profile]; 872 if (ptr) 873 goto ok; 874 ptr = tomoyo_alloc_element(sizeof(*ptr)); 875 if (!ptr) 876 goto ok; 877 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 878 ptr->value[i] = tomoyo_control_array[i].current_value; 879 mb(); /* Avoid out-of-order execution. */ 880 tomoyo_profile_ptr[profile] = ptr; 881 ok: 882 mutex_unlock(&lock); 883 /***** EXCLUSIVE SECTION END *****/ 884 return ptr; 885} 886 887/** 888 * tomoyo_write_profile - Write to profile table. 889 * 890 * @head: Pointer to "struct tomoyo_io_buffer". 891 * 892 * Returns 0 on success, negative value otherwise. 893 */ 894static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 895{ 896 char *data = head->write_buf; 897 unsigned int i; 898 unsigned int value; 899 char *cp; 900 struct tomoyo_profile *profile; 901 unsigned long num; 902 903 cp = strchr(data, '-'); 904 if (cp) 905 *cp = '\0'; 906 if (strict_strtoul(data, 10, &num)) 907 return -EINVAL; 908 if (cp) 909 data = cp + 1; 910 profile = tomoyo_find_or_assign_new_profile(num); 911 if (!profile) 912 return -EINVAL; 913 cp = strchr(data, '='); 914 if (!cp) 915 return -EINVAL; 916 *cp = '\0'; 917 if (!strcmp(data, "COMMENT")) { 918 profile->comment = tomoyo_save_name(cp + 1); 919 return 0; 920 } 921 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 922 if (strcmp(data, tomoyo_control_array[i].keyword)) 923 continue; 924 if (sscanf(cp + 1, "%u", &value) != 1) { 925 int j; 926 const char **modes; 927 switch (i) { 928 case TOMOYO_VERBOSE: 929 modes = tomoyo_mode_2; 930 break; 931 default: 932 modes = tomoyo_mode_4; 933 break; 934 } 935 for (j = 0; j < 4; j++) { 936 if (strcmp(cp + 1, modes[j])) 937 continue; 938 value = j; 939 break; 940 } 941 if (j == 4) 942 return -EINVAL; 943 } else if (value > tomoyo_control_array[i].max_value) { 944 value = tomoyo_control_array[i].max_value; 945 } 946 profile->value[i] = value; 947 return 0; 948 } 949 return -EINVAL; 950} 951 952/** 953 * tomoyo_read_profile - Read from profile table. 954 * 955 * @head: Pointer to "struct tomoyo_io_buffer". 956 * 957 * Returns 0. 958 */ 959static int tomoyo_read_profile(struct tomoyo_io_buffer *head) 960{ 961 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; 962 int step; 963 964 if (head->read_eof) 965 return 0; 966 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; 967 step++) { 968 const u8 index = step / total; 969 u8 type = step % total; 970 const struct tomoyo_profile *profile 971 = tomoyo_profile_ptr[index]; 972 head->read_step = step; 973 if (!profile) 974 continue; 975 if (!type) { /* Print profile' comment tag. */ 976 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", 977 index, profile->comment ? 978 profile->comment->name : "")) 979 break; 980 continue; 981 } 982 type--; 983 if (type < TOMOYO_MAX_CONTROL_INDEX) { 984 const unsigned int value = profile->value[type]; 985 const char **modes = NULL; 986 const char *keyword 987 = tomoyo_control_array[type].keyword; 988 switch (tomoyo_control_array[type].max_value) { 989 case 3: 990 modes = tomoyo_mode_4; 991 break; 992 case 1: 993 modes = tomoyo_mode_2; 994 break; 995 } 996 if (modes) { 997 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index, 998 keyword, modes[value])) 999 break; 1000 } else { 1001 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index, 1002 keyword, value)) 1003 break; 1004 } 1005 } 1006 } 1007 if (step == TOMOYO_MAX_PROFILES * total) 1008 head->read_eof = true; 1009 return 0; 1010} 1011 1012/* Structure for policy manager. */ 1013struct tomoyo_policy_manager_entry { 1014 struct list_head list; 1015 /* A path to program or a domainname. */ 1016 const struct tomoyo_path_info *manager; 1017 bool is_domain; /* True if manager is a domainname. */ 1018 bool is_deleted; /* True if this entry is deleted. */ 1019}; 1020 1021/* The list for "struct tomoyo_policy_manager_entry". */ 1022static LIST_HEAD(tomoyo_policy_manager_list); 1023static DECLARE_RWSEM(tomoyo_policy_manager_list_lock); 1024 1025/** 1026 * tomoyo_update_manager_entry - Add a manager entry. 1027 * 1028 * @manager: The path to manager or the domainnamme. 1029 * @is_delete: True if it is a delete request. 1030 * 1031 * Returns 0 on success, negative value otherwise. 1032 */ 1033static int tomoyo_update_manager_entry(const char *manager, 1034 const bool is_delete) 1035{ 1036 struct tomoyo_policy_manager_entry *new_entry; 1037 struct tomoyo_policy_manager_entry *ptr; 1038 const struct tomoyo_path_info *saved_manager; 1039 int error = -ENOMEM; 1040 bool is_domain = false; 1041 1042 if (tomoyo_is_domain_def(manager)) { 1043 if (!tomoyo_is_correct_domain(manager, __func__)) 1044 return -EINVAL; 1045 is_domain = true; 1046 } else { 1047 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1048 return -EINVAL; 1049 } 1050 saved_manager = tomoyo_save_name(manager); 1051 if (!saved_manager) 1052 return -ENOMEM; 1053 /***** EXCLUSIVE SECTION START *****/ 1054 down_write(&tomoyo_policy_manager_list_lock); 1055 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1056 if (ptr->manager != saved_manager) 1057 continue; 1058 ptr->is_deleted = is_delete; 1059 error = 0; 1060 goto out; 1061 } 1062 if (is_delete) { 1063 error = -ENOENT; 1064 goto out; 1065 } 1066 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 1067 if (!new_entry) 1068 goto out; 1069 new_entry->manager = saved_manager; 1070 new_entry->is_domain = is_domain; 1071 list_add_tail(&new_entry->list, &tomoyo_policy_manager_list); 1072 error = 0; 1073 out: 1074 up_write(&tomoyo_policy_manager_list_lock); 1075 /***** EXCLUSIVE SECTION END *****/ 1076 return error; 1077} 1078 1079/** 1080 * tomoyo_write_manager_policy - Write manager policy. 1081 * 1082 * @head: Pointer to "struct tomoyo_io_buffer". 1083 * 1084 * Returns 0 on success, negative value otherwise. 1085 */ 1086static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1087{ 1088 char *data = head->write_buf; 1089 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1090 1091 if (!strcmp(data, "manage_by_non_root")) { 1092 tomoyo_manage_by_non_root = !is_delete; 1093 return 0; 1094 } 1095 return tomoyo_update_manager_entry(data, is_delete); 1096} 1097 1098/** 1099 * tomoyo_read_manager_policy - Read manager policy. 1100 * 1101 * @head: Pointer to "struct tomoyo_io_buffer". 1102 * 1103 * Returns 0. 1104 */ 1105static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1106{ 1107 struct list_head *pos; 1108 bool done = true; 1109 1110 if (head->read_eof) 1111 return 0; 1112 down_read(&tomoyo_policy_manager_list_lock); 1113 list_for_each_cookie(pos, head->read_var2, 1114 &tomoyo_policy_manager_list) { 1115 struct tomoyo_policy_manager_entry *ptr; 1116 ptr = list_entry(pos, struct tomoyo_policy_manager_entry, 1117 list); 1118 if (ptr->is_deleted) 1119 continue; 1120 if (!tomoyo_io_printf(head, "%s\n", ptr->manager->name)) { 1121 done = false; 1122 break; 1123 } 1124 } 1125 up_read(&tomoyo_policy_manager_list_lock); 1126 head->read_eof = done; 1127 return 0; 1128} 1129 1130/** 1131 * tomoyo_is_policy_manager - Check whether the current process is a policy manager. 1132 * 1133 * Returns true if the current process is permitted to modify policy 1134 * via /sys/kernel/security/tomoyo/ interface. 1135 */ 1136static bool tomoyo_is_policy_manager(void) 1137{ 1138 struct tomoyo_policy_manager_entry *ptr; 1139 const char *exe; 1140 const struct task_struct *task = current; 1141 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; 1142 bool found = false; 1143 1144 if (!tomoyo_policy_loaded) 1145 return true; 1146 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 1147 return false; 1148 down_read(&tomoyo_policy_manager_list_lock); 1149 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1150 if (!ptr->is_deleted && ptr->is_domain 1151 && !tomoyo_pathcmp(domainname, ptr->manager)) { 1152 found = true; 1153 break; 1154 } 1155 } 1156 up_read(&tomoyo_policy_manager_list_lock); 1157 if (found) 1158 return true; 1159 exe = tomoyo_get_exe(); 1160 if (!exe) 1161 return false; 1162 down_read(&tomoyo_policy_manager_list_lock); 1163 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1164 if (!ptr->is_deleted && !ptr->is_domain 1165 && !strcmp(exe, ptr->manager->name)) { 1166 found = true; 1167 break; 1168 } 1169 } 1170 up_read(&tomoyo_policy_manager_list_lock); 1171 if (!found) { /* Reduce error messages. */ 1172 static pid_t last_pid; 1173 const pid_t pid = current->pid; 1174 if (last_pid != pid) { 1175 printk(KERN_WARNING "%s ( %s ) is not permitted to " 1176 "update policies.\n", domainname->name, exe); 1177 last_pid = pid; 1178 } 1179 } 1180 tomoyo_free(exe); 1181 return found; 1182} 1183 1184/** 1185 * tomoyo_is_select_one - Parse select command. 1186 * 1187 * @head: Pointer to "struct tomoyo_io_buffer". 1188 * @data: String to parse. 1189 * 1190 * Returns true on success, false otherwise. 1191 */ 1192static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1193 const char *data) 1194{ 1195 unsigned int pid; 1196 struct tomoyo_domain_info *domain = NULL; 1197 1198 if (sscanf(data, "pid=%u", &pid) == 1) { 1199 struct task_struct *p; 1200 /***** CRITICAL SECTION START *****/ 1201 read_lock(&tasklist_lock); 1202 p = find_task_by_vpid(pid); 1203 if (p) 1204 domain = tomoyo_real_domain(p); 1205 read_unlock(&tasklist_lock); 1206 /***** CRITICAL SECTION END *****/ 1207 } else if (!strncmp(data, "domain=", 7)) { 1208 if (tomoyo_is_domain_def(data + 7)) { 1209 down_read(&tomoyo_domain_list_lock); 1210 domain = tomoyo_find_domain(data + 7); 1211 up_read(&tomoyo_domain_list_lock); 1212 } 1213 } else 1214 return false; 1215 head->write_var1 = domain; 1216 /* Accessing read_buf is safe because head->io_sem is held. */ 1217 if (!head->read_buf) 1218 return true; /* Do nothing if open(O_WRONLY). */ 1219 head->read_avail = 0; 1220 tomoyo_io_printf(head, "# select %s\n", data); 1221 head->read_single_domain = true; 1222 head->read_eof = !domain; 1223 if (domain) { 1224 struct tomoyo_domain_info *d; 1225 head->read_var1 = NULL; 1226 down_read(&tomoyo_domain_list_lock); 1227 list_for_each_entry(d, &tomoyo_domain_list, list) { 1228 if (d == domain) 1229 break; 1230 head->read_var1 = &d->list; 1231 } 1232 up_read(&tomoyo_domain_list_lock); 1233 head->read_var2 = NULL; 1234 head->read_bit = 0; 1235 head->read_step = 0; 1236 if (domain->is_deleted) 1237 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 1238 } 1239 return true; 1240} 1241 1242/** 1243 * tomoyo_write_domain_policy - Write domain policy. 1244 * 1245 * @head: Pointer to "struct tomoyo_io_buffer". 1246 * 1247 * Returns 0 on success, negative value otherwise. 1248 */ 1249static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1250{ 1251 char *data = head->write_buf; 1252 struct tomoyo_domain_info *domain = head->write_var1; 1253 bool is_delete = false; 1254 bool is_select = false; 1255 bool is_undelete = false; 1256 unsigned int profile; 1257 1258 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) 1259 is_delete = true; 1260 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) 1261 is_select = true; 1262 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_UNDELETE)) 1263 is_undelete = true; 1264 if (is_select && tomoyo_is_select_one(head, data)) 1265 return 0; 1266 /* Don't allow updating policies by non manager programs. */ 1267 if (!tomoyo_is_policy_manager()) 1268 return -EPERM; 1269 if (tomoyo_is_domain_def(data)) { 1270 domain = NULL; 1271 if (is_delete) 1272 tomoyo_delete_domain(data); 1273 else if (is_select) { 1274 down_read(&tomoyo_domain_list_lock); 1275 domain = tomoyo_find_domain(data); 1276 up_read(&tomoyo_domain_list_lock); 1277 } else if (is_undelete) 1278 domain = tomoyo_undelete_domain(data); 1279 else 1280 domain = tomoyo_find_or_assign_new_domain(data, 0); 1281 head->write_var1 = domain; 1282 return 0; 1283 } 1284 if (!domain) 1285 return -EINVAL; 1286 1287 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1 1288 && profile < TOMOYO_MAX_PROFILES) { 1289 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 1290 domain->profile = (u8) profile; 1291 return 0; 1292 } 1293 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1294 tomoyo_set_domain_flag(domain, is_delete, 1295 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ); 1296 return 0; 1297 } 1298 return tomoyo_write_file_policy(data, domain, is_delete); 1299} 1300 1301/** 1302 * tomoyo_print_single_path_acl - Print a single path ACL entry. 1303 * 1304 * @head: Pointer to "struct tomoyo_io_buffer". 1305 * @ptr: Pointer to "struct tomoyo_single_path_acl_record". 1306 * 1307 * Returns true on success, false otherwise. 1308 */ 1309static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head, 1310 struct tomoyo_single_path_acl_record * 1311 ptr) 1312{ 1313 int pos; 1314 u8 bit; 1315 const char *atmark = ""; 1316 const char *filename; 1317 const u16 perm = ptr->perm; 1318 1319 filename = ptr->filename->name; 1320 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION; 1321 bit++) { 1322 const char *msg; 1323 if (!(perm & (1 << bit))) 1324 continue; 1325 /* Print "read/write" instead of "read" and "write". */ 1326 if ((bit == TOMOYO_TYPE_READ_ACL || 1327 bit == TOMOYO_TYPE_WRITE_ACL) 1328 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) 1329 continue; 1330 msg = tomoyo_sp2keyword(bit); 1331 pos = head->read_avail; 1332 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg, 1333 atmark, filename)) 1334 goto out; 1335 } 1336 head->read_bit = 0; 1337 return true; 1338 out: 1339 head->read_bit = bit; 1340 head->read_avail = pos; 1341 return false; 1342} 1343 1344/** 1345 * tomoyo_print_double_path_acl - Print a double path ACL entry. 1346 * 1347 * @head: Pointer to "struct tomoyo_io_buffer". 1348 * @ptr: Pointer to "struct tomoyo_double_path_acl_record". 1349 * 1350 * Returns true on success, false otherwise. 1351 */ 1352static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, 1353 struct tomoyo_double_path_acl_record * 1354 ptr) 1355{ 1356 int pos; 1357 const char *atmark1 = ""; 1358 const char *atmark2 = ""; 1359 const char *filename1; 1360 const char *filename2; 1361 const u8 perm = ptr->perm; 1362 u8 bit; 1363 1364 filename1 = ptr->filename1->name; 1365 filename2 = ptr->filename2->name; 1366 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION; 1367 bit++) { 1368 const char *msg; 1369 if (!(perm & (1 << bit))) 1370 continue; 1371 msg = tomoyo_dp2keyword(bit); 1372 pos = head->read_avail; 1373 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg, 1374 atmark1, filename1, atmark2, filename2)) 1375 goto out; 1376 } 1377 head->read_bit = 0; 1378 return true; 1379 out: 1380 head->read_bit = bit; 1381 head->read_avail = pos; 1382 return false; 1383} 1384 1385/** 1386 * tomoyo_print_entry - Print an ACL entry. 1387 * 1388 * @head: Pointer to "struct tomoyo_io_buffer". 1389 * @ptr: Pointer to an ACL entry. 1390 * 1391 * Returns true on success, false otherwise. 1392 */ 1393static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1394 struct tomoyo_acl_info *ptr) 1395{ 1396 const u8 acl_type = tomoyo_acl_type2(ptr); 1397 1398 if (acl_type & TOMOYO_ACL_DELETED) 1399 return true; 1400 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { 1401 struct tomoyo_single_path_acl_record *acl 1402 = container_of(ptr, 1403 struct tomoyo_single_path_acl_record, 1404 head); 1405 return tomoyo_print_single_path_acl(head, acl); 1406 } 1407 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) { 1408 struct tomoyo_double_path_acl_record *acl 1409 = container_of(ptr, 1410 struct tomoyo_double_path_acl_record, 1411 head); 1412 return tomoyo_print_double_path_acl(head, acl); 1413 } 1414 BUG(); /* This must not happen. */ 1415 return false; 1416} 1417 1418/** 1419 * tomoyo_read_domain_policy - Read domain policy. 1420 * 1421 * @head: Pointer to "struct tomoyo_io_buffer". 1422 * 1423 * Returns 0. 1424 */ 1425static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1426{ 1427 struct list_head *dpos; 1428 struct list_head *apos; 1429 bool done = true; 1430 1431 if (head->read_eof) 1432 return 0; 1433 if (head->read_step == 0) 1434 head->read_step = 1; 1435 down_read(&tomoyo_domain_list_lock); 1436 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { 1437 struct tomoyo_domain_info *domain; 1438 const char *quota_exceeded = ""; 1439 const char *transition_failed = ""; 1440 const char *ignore_global_allow_read = ""; 1441 domain = list_entry(dpos, struct tomoyo_domain_info, list); 1442 if (head->read_step != 1) 1443 goto acl_loop; 1444 if (domain->is_deleted && !head->read_single_domain) 1445 continue; 1446 /* Print domainname and flags. */ 1447 if (domain->quota_warned) 1448 quota_exceeded = "quota_exceeded\n"; 1449 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) 1450 transition_failed = "transition_failed\n"; 1451 if (domain->flags & 1452 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) 1453 ignore_global_allow_read 1454 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1455 if (!tomoyo_io_printf(head, 1456 "%s\n" TOMOYO_KEYWORD_USE_PROFILE "%u\n" 1457 "%s%s%s\n", domain->domainname->name, 1458 domain->profile, quota_exceeded, 1459 transition_failed, 1460 ignore_global_allow_read)) { 1461 done = false; 1462 break; 1463 } 1464 head->read_step = 2; 1465acl_loop: 1466 if (head->read_step == 3) 1467 goto tail_mark; 1468 /* Print ACL entries in the domain. */ 1469 down_read(&tomoyo_domain_acl_info_list_lock); 1470 list_for_each_cookie(apos, head->read_var2, 1471 &domain->acl_info_list) { 1472 struct tomoyo_acl_info *ptr 1473 = list_entry(apos, struct tomoyo_acl_info, 1474 list); 1475 if (!tomoyo_print_entry(head, ptr)) { 1476 done = false; 1477 break; 1478 } 1479 } 1480 up_read(&tomoyo_domain_acl_info_list_lock); 1481 if (!done) 1482 break; 1483 head->read_step = 3; 1484tail_mark: 1485 if (!tomoyo_io_printf(head, "\n")) { 1486 done = false; 1487 break; 1488 } 1489 head->read_step = 1; 1490 if (head->read_single_domain) 1491 break; 1492 } 1493 up_read(&tomoyo_domain_list_lock); 1494 head->read_eof = done; 1495 return 0; 1496} 1497 1498/** 1499 * tomoyo_write_domain_profile - Assign profile for specified domain. 1500 * 1501 * @head: Pointer to "struct tomoyo_io_buffer". 1502 * 1503 * Returns 0 on success, -EINVAL otherwise. 1504 * 1505 * This is equivalent to doing 1506 * 1507 * ( echo "select " $domainname; echo "use_profile " $profile ) | 1508 * /usr/lib/ccs/loadpolicy -d 1509 */ 1510static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1511{ 1512 char *data = head->write_buf; 1513 char *cp = strchr(data, ' '); 1514 struct tomoyo_domain_info *domain; 1515 unsigned long profile; 1516 1517 if (!cp) 1518 return -EINVAL; 1519 *cp = '\0'; 1520 down_read(&tomoyo_domain_list_lock); 1521 domain = tomoyo_find_domain(cp + 1); 1522 up_read(&tomoyo_domain_list_lock); 1523 if (strict_strtoul(data, 10, &profile)) 1524 return -EINVAL; 1525 if (domain && profile < TOMOYO_MAX_PROFILES 1526 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)) 1527 domain->profile = (u8) profile; 1528 return 0; 1529} 1530 1531/** 1532 * tomoyo_read_domain_profile - Read only domainname and profile. 1533 * 1534 * @head: Pointer to "struct tomoyo_io_buffer". 1535 * 1536 * Returns list of profile number and domainname pairs. 1537 * 1538 * This is equivalent to doing 1539 * 1540 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy | 1541 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) 1542 * domainname = $0; } else if ( $1 == "use_profile" ) { 1543 * print $2 " " domainname; domainname = ""; } } ; ' 1544 */ 1545static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1546{ 1547 struct list_head *pos; 1548 bool done = true; 1549 1550 if (head->read_eof) 1551 return 0; 1552 down_read(&tomoyo_domain_list_lock); 1553 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { 1554 struct tomoyo_domain_info *domain; 1555 domain = list_entry(pos, struct tomoyo_domain_info, list); 1556 if (domain->is_deleted) 1557 continue; 1558 if (!tomoyo_io_printf(head, "%u %s\n", domain->profile, 1559 domain->domainname->name)) { 1560 done = false; 1561 break; 1562 } 1563 } 1564 up_read(&tomoyo_domain_list_lock); 1565 head->read_eof = done; 1566 return 0; 1567} 1568 1569/** 1570 * tomoyo_write_pid: Specify PID to obtain domainname. 1571 * 1572 * @head: Pointer to "struct tomoyo_io_buffer". 1573 * 1574 * Returns 0. 1575 */ 1576static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1577{ 1578 unsigned long pid; 1579 /* No error check. */ 1580 strict_strtoul(head->write_buf, 10, &pid); 1581 head->read_step = (int) pid; 1582 head->read_eof = false; 1583 return 0; 1584} 1585 1586/** 1587 * tomoyo_read_pid - Get domainname of the specified PID. 1588 * 1589 * @head: Pointer to "struct tomoyo_io_buffer". 1590 * 1591 * Returns the domainname which the specified PID is in on success, 1592 * empty string otherwise. 1593 * The PID is specified by tomoyo_write_pid() so that the user can obtain 1594 * using read()/write() interface rather than sysctl() interface. 1595 */ 1596static int tomoyo_read_pid(struct tomoyo_io_buffer *head) 1597{ 1598 if (head->read_avail == 0 && !head->read_eof) { 1599 const int pid = head->read_step; 1600 struct task_struct *p; 1601 struct tomoyo_domain_info *domain = NULL; 1602 /***** CRITICAL SECTION START *****/ 1603 read_lock(&tasklist_lock); 1604 p = find_task_by_vpid(pid); 1605 if (p) 1606 domain = tomoyo_real_domain(p); 1607 read_unlock(&tasklist_lock); 1608 /***** CRITICAL SECTION END *****/ 1609 if (domain) 1610 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1611 domain->domainname->name); 1612 head->read_eof = true; 1613 } 1614 return 0; 1615} 1616 1617/** 1618 * tomoyo_write_exception_policy - Write exception policy. 1619 * 1620 * @head: Pointer to "struct tomoyo_io_buffer". 1621 * 1622 * Returns 0 on success, negative value otherwise. 1623 */ 1624static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1625{ 1626 char *data = head->write_buf; 1627 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1628 1629 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN)) 1630 return tomoyo_write_domain_keeper_policy(data, false, 1631 is_delete); 1632 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN)) 1633 return tomoyo_write_domain_keeper_policy(data, true, is_delete); 1634 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN)) 1635 return tomoyo_write_domain_initializer_policy(data, false, 1636 is_delete); 1637 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN)) 1638 return tomoyo_write_domain_initializer_policy(data, true, 1639 is_delete); 1640 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS)) 1641 return tomoyo_write_alias_policy(data, is_delete); 1642 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ)) 1643 return tomoyo_write_globally_readable_policy(data, is_delete); 1644 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN)) 1645 return tomoyo_write_pattern_policy(data, is_delete); 1646 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) 1647 return tomoyo_write_no_rewrite_policy(data, is_delete); 1648 return -EINVAL; 1649} 1650 1651/** 1652 * tomoyo_read_exception_policy - Read exception policy. 1653 * 1654 * @head: Pointer to "struct tomoyo_io_buffer". 1655 * 1656 * Returns 0 on success, -EINVAL otherwise. 1657 */ 1658static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1659{ 1660 if (!head->read_eof) { 1661 switch (head->read_step) { 1662 case 0: 1663 head->read_var2 = NULL; 1664 head->read_step = 1; 1665 case 1: 1666 if (!tomoyo_read_domain_keeper_policy(head)) 1667 break; 1668 head->read_var2 = NULL; 1669 head->read_step = 2; 1670 case 2: 1671 if (!tomoyo_read_globally_readable_policy(head)) 1672 break; 1673 head->read_var2 = NULL; 1674 head->read_step = 3; 1675 case 3: 1676 head->read_var2 = NULL; 1677 head->read_step = 4; 1678 case 4: 1679 if (!tomoyo_read_domain_initializer_policy(head)) 1680 break; 1681 head->read_var2 = NULL; 1682 head->read_step = 5; 1683 case 5: 1684 if (!tomoyo_read_alias_policy(head)) 1685 break; 1686 head->read_var2 = NULL; 1687 head->read_step = 6; 1688 case 6: 1689 head->read_var2 = NULL; 1690 head->read_step = 7; 1691 case 7: 1692 if (!tomoyo_read_file_pattern(head)) 1693 break; 1694 head->read_var2 = NULL; 1695 head->read_step = 8; 1696 case 8: 1697 if (!tomoyo_read_no_rewrite_policy(head)) 1698 break; 1699 head->read_var2 = NULL; 1700 head->read_step = 9; 1701 case 9: 1702 head->read_eof = true; 1703 break; 1704 default: 1705 return -EINVAL; 1706 } 1707 } 1708 return 0; 1709} 1710 1711/* path to policy loader */ 1712static const char *tomoyo_loader = "/sbin/tomoyo-init"; 1713 1714/** 1715 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 1716 * 1717 * Returns true if /sbin/tomoyo-init exists, false otherwise. 1718 */ 1719static bool tomoyo_policy_loader_exists(void) 1720{ 1721 /* 1722 * Don't activate MAC if the policy loader doesn't exist. 1723 * If the initrd includes /sbin/init but real-root-dev has not 1724 * mounted on / yet, activating MAC will block the system since 1725 * policies are not loaded yet. 1726 * Thus, let do_execve() call this function everytime. 1727 */ 1728 struct nameidata nd; 1729 1730 if (path_lookup(tomoyo_loader, LOOKUP_FOLLOW, &nd)) { 1731 printk(KERN_INFO "Not activating Mandatory Access Control now " 1732 "since %s doesn't exist.\n", tomoyo_loader); 1733 return false; 1734 } 1735 path_put(&nd.path); 1736 return true; 1737} 1738 1739/** 1740 * tomoyo_load_policy - Run external policy loader to load policy. 1741 * 1742 * @filename: The program about to start. 1743 * 1744 * This function checks whether @filename is /sbin/init , and if so 1745 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init 1746 * and then continues invocation of /sbin/init. 1747 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and 1748 * writes to /sys/kernel/security/tomoyo/ interfaces. 1749 * 1750 * Returns nothing. 1751 */ 1752void tomoyo_load_policy(const char *filename) 1753{ 1754 char *argv[2]; 1755 char *envp[3]; 1756 1757 if (tomoyo_policy_loaded) 1758 return; 1759 /* 1760 * Check filename is /sbin/init or /sbin/tomoyo-start. 1761 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't 1762 * be passed. 1763 * You can create /sbin/tomoyo-start by 1764 * "ln -s /bin/true /sbin/tomoyo-start". 1765 */ 1766 if (strcmp(filename, "/sbin/init") && 1767 strcmp(filename, "/sbin/tomoyo-start")) 1768 return; 1769 if (!tomoyo_policy_loader_exists()) 1770 return; 1771 1772 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 1773 tomoyo_loader); 1774 argv[0] = (char *) tomoyo_loader; 1775 argv[1] = NULL; 1776 envp[0] = "HOME=/"; 1777 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 1778 envp[2] = NULL; 1779 call_usermodehelper(argv[0], argv, envp, 1); 1780 1781 printk(KERN_INFO "TOMOYO: 2.2.0-pre 2009/02/01\n"); 1782 printk(KERN_INFO "Mandatory Access Control activated.\n"); 1783 tomoyo_policy_loaded = true; 1784 { /* Check all profiles currently assigned to domains are defined. */ 1785 struct tomoyo_domain_info *domain; 1786 down_read(&tomoyo_domain_list_lock); 1787 list_for_each_entry(domain, &tomoyo_domain_list, list) { 1788 const u8 profile = domain->profile; 1789 if (tomoyo_profile_ptr[profile]) 1790 continue; 1791 panic("Profile %u (used by '%s') not defined.\n", 1792 profile, domain->domainname->name); 1793 } 1794 up_read(&tomoyo_domain_list_lock); 1795 } 1796} 1797 1798/** 1799 * tomoyo_read_version: Get version. 1800 * 1801 * @head: Pointer to "struct tomoyo_io_buffer". 1802 * 1803 * Returns version information. 1804 */ 1805static int tomoyo_read_version(struct tomoyo_io_buffer *head) 1806{ 1807 if (!head->read_eof) { 1808 tomoyo_io_printf(head, "2.2.0-pre"); 1809 head->read_eof = true; 1810 } 1811 return 0; 1812} 1813 1814/** 1815 * tomoyo_read_self_domain - Get the current process's domainname. 1816 * 1817 * @head: Pointer to "struct tomoyo_io_buffer". 1818 * 1819 * Returns the current process's domainname. 1820 */ 1821static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head) 1822{ 1823 if (!head->read_eof) { 1824 /* 1825 * tomoyo_domain()->domainname != NULL 1826 * because every process belongs to a domain and 1827 * the domain's name cannot be NULL. 1828 */ 1829 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); 1830 head->read_eof = true; 1831 } 1832 return 0; 1833} 1834 1835/** 1836 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 1837 * 1838 * @type: Type of interface. 1839 * @file: Pointer to "struct file". 1840 * 1841 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 1842 */ 1843static int tomoyo_open_control(const u8 type, struct file *file) 1844{ 1845 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head)); 1846 1847 if (!head) 1848 return -ENOMEM; 1849 mutex_init(&head->io_sem); 1850 switch (type) { 1851 case TOMOYO_DOMAINPOLICY: 1852 /* /sys/kernel/security/tomoyo/domain_policy */ 1853 head->write = tomoyo_write_domain_policy; 1854 head->read = tomoyo_read_domain_policy; 1855 break; 1856 case TOMOYO_EXCEPTIONPOLICY: 1857 /* /sys/kernel/security/tomoyo/exception_policy */ 1858 head->write = tomoyo_write_exception_policy; 1859 head->read = tomoyo_read_exception_policy; 1860 break; 1861 case TOMOYO_SELFDOMAIN: 1862 /* /sys/kernel/security/tomoyo/self_domain */ 1863 head->read = tomoyo_read_self_domain; 1864 break; 1865 case TOMOYO_DOMAIN_STATUS: 1866 /* /sys/kernel/security/tomoyo/.domain_status */ 1867 head->write = tomoyo_write_domain_profile; 1868 head->read = tomoyo_read_domain_profile; 1869 break; 1870 case TOMOYO_PROCESS_STATUS: 1871 /* /sys/kernel/security/tomoyo/.process_status */ 1872 head->write = tomoyo_write_pid; 1873 head->read = tomoyo_read_pid; 1874 break; 1875 case TOMOYO_VERSION: 1876 /* /sys/kernel/security/tomoyo/version */ 1877 head->read = tomoyo_read_version; 1878 head->readbuf_size = 128; 1879 break; 1880 case TOMOYO_MEMINFO: 1881 /* /sys/kernel/security/tomoyo/meminfo */ 1882 head->write = tomoyo_write_memory_quota; 1883 head->read = tomoyo_read_memory_counter; 1884 head->readbuf_size = 512; 1885 break; 1886 case TOMOYO_PROFILE: 1887 /* /sys/kernel/security/tomoyo/profile */ 1888 head->write = tomoyo_write_profile; 1889 head->read = tomoyo_read_profile; 1890 break; 1891 case TOMOYO_MANAGER: 1892 /* /sys/kernel/security/tomoyo/manager */ 1893 head->write = tomoyo_write_manager_policy; 1894 head->read = tomoyo_read_manager_policy; 1895 break; 1896 } 1897 if (!(file->f_mode & FMODE_READ)) { 1898 /* 1899 * No need to allocate read_buf since it is not opened 1900 * for reading. 1901 */ 1902 head->read = NULL; 1903 } else { 1904 if (!head->readbuf_size) 1905 head->readbuf_size = 4096 * 2; 1906 head->read_buf = tomoyo_alloc(head->readbuf_size); 1907 if (!head->read_buf) { 1908 tomoyo_free(head); 1909 return -ENOMEM; 1910 } 1911 } 1912 if (!(file->f_mode & FMODE_WRITE)) { 1913 /* 1914 * No need to allocate write_buf since it is not opened 1915 * for writing. 1916 */ 1917 head->write = NULL; 1918 } else if (head->write) { 1919 head->writebuf_size = 4096 * 2; 1920 head->write_buf = tomoyo_alloc(head->writebuf_size); 1921 if (!head->write_buf) { 1922 tomoyo_free(head->read_buf); 1923 tomoyo_free(head); 1924 return -ENOMEM; 1925 } 1926 } 1927 file->private_data = head; 1928 /* 1929 * Call the handler now if the file is 1930 * /sys/kernel/security/tomoyo/self_domain 1931 * so that the user can use 1932 * cat < /sys/kernel/security/tomoyo/self_domain" 1933 * to know the current process's domainname. 1934 */ 1935 if (type == TOMOYO_SELFDOMAIN) 1936 tomoyo_read_control(file, NULL, 0); 1937 return 0; 1938} 1939 1940/** 1941 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 1942 * 1943 * @file: Pointer to "struct file". 1944 * @buffer: Poiner to buffer to write to. 1945 * @buffer_len: Size of @buffer. 1946 * 1947 * Returns bytes read on success, negative value otherwise. 1948 */ 1949static int tomoyo_read_control(struct file *file, char __user *buffer, 1950 const int buffer_len) 1951{ 1952 int len = 0; 1953 struct tomoyo_io_buffer *head = file->private_data; 1954 char *cp; 1955 1956 if (!head->read) 1957 return -ENOSYS; 1958 if (mutex_lock_interruptible(&head->io_sem)) 1959 return -EINTR; 1960 /* Call the policy handler. */ 1961 len = head->read(head); 1962 if (len < 0) 1963 goto out; 1964 /* Write to buffer. */ 1965 len = head->read_avail; 1966 if (len > buffer_len) 1967 len = buffer_len; 1968 if (!len) 1969 goto out; 1970 /* head->read_buf changes by some functions. */ 1971 cp = head->read_buf; 1972 if (copy_to_user(buffer, cp, len)) { 1973 len = -EFAULT; 1974 goto out; 1975 } 1976 head->read_avail -= len; 1977 memmove(cp, cp + len, head->read_avail); 1978 out: 1979 mutex_unlock(&head->io_sem); 1980 return len; 1981} 1982 1983/** 1984 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 1985 * 1986 * @file: Pointer to "struct file". 1987 * @buffer: Pointer to buffer to read from. 1988 * @buffer_len: Size of @buffer. 1989 * 1990 * Returns @buffer_len on success, negative value otherwise. 1991 */ 1992static int tomoyo_write_control(struct file *file, const char __user *buffer, 1993 const int buffer_len) 1994{ 1995 struct tomoyo_io_buffer *head = file->private_data; 1996 int error = buffer_len; 1997 int avail_len = buffer_len; 1998 char *cp0 = head->write_buf; 1999 2000 if (!head->write) 2001 return -ENOSYS; 2002 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2003 return -EFAULT; 2004 /* Don't allow updating policies by non manager programs. */ 2005 if (head->write != tomoyo_write_pid && 2006 head->write != tomoyo_write_domain_policy && 2007 !tomoyo_is_policy_manager()) 2008 return -EPERM; 2009 if (mutex_lock_interruptible(&head->io_sem)) 2010 return -EINTR; 2011 /* Read a line and dispatch it to the policy handler. */ 2012 while (avail_len > 0) { 2013 char c; 2014 if (head->write_avail >= head->writebuf_size - 1) { 2015 error = -ENOMEM; 2016 break; 2017 } else if (get_user(c, buffer)) { 2018 error = -EFAULT; 2019 break; 2020 } 2021 buffer++; 2022 avail_len--; 2023 cp0[head->write_avail++] = c; 2024 if (c != '\n') 2025 continue; 2026 cp0[head->write_avail - 1] = '\0'; 2027 head->write_avail = 0; 2028 tomoyo_normalize_line(cp0); 2029 head->write(head); 2030 } 2031 mutex_unlock(&head->io_sem); 2032 return error; 2033} 2034 2035/** 2036 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2037 * 2038 * @file: Pointer to "struct file". 2039 * 2040 * Releases memory and returns 0. 2041 */ 2042static int tomoyo_close_control(struct file *file) 2043{ 2044 struct tomoyo_io_buffer *head = file->private_data; 2045 2046 /* Release memory used for policy I/O. */ 2047 tomoyo_free(head->read_buf); 2048 head->read_buf = NULL; 2049 tomoyo_free(head->write_buf); 2050 head->write_buf = NULL; 2051 tomoyo_free(head); 2052 head = NULL; 2053 file->private_data = NULL; 2054 return 0; 2055} 2056 2057/** 2058 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry. 2059 * 2060 * @acl_type: Type of ACL entry. 2061 * 2062 * Returns pointer to the ACL entry on success, NULL otherwise. 2063 */ 2064void *tomoyo_alloc_acl_element(const u8 acl_type) 2065{ 2066 int len; 2067 struct tomoyo_acl_info *ptr; 2068 2069 switch (acl_type) { 2070 case TOMOYO_TYPE_SINGLE_PATH_ACL: 2071 len = sizeof(struct tomoyo_single_path_acl_record); 2072 break; 2073 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 2074 len = sizeof(struct tomoyo_double_path_acl_record); 2075 break; 2076 default: 2077 return NULL; 2078 } 2079 ptr = tomoyo_alloc_element(len); 2080 if (!ptr) 2081 return NULL; 2082 ptr->type = acl_type; 2083 return ptr; 2084} 2085 2086/** 2087 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2088 * 2089 * @inode: Pointer to "struct inode". 2090 * @file: Pointer to "struct file". 2091 * 2092 * Returns 0 on success, negative value otherwise. 2093 */ 2094static int tomoyo_open(struct inode *inode, struct file *file) 2095{ 2096 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private) 2097 - ((u8 *) NULL); 2098 return tomoyo_open_control(key, file); 2099} 2100 2101/** 2102 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface. 2103 * 2104 * @inode: Pointer to "struct inode". 2105 * @file: Pointer to "struct file". 2106 * 2107 * Returns 0 on success, negative value otherwise. 2108 */ 2109static int tomoyo_release(struct inode *inode, struct file *file) 2110{ 2111 return tomoyo_close_control(file); 2112} 2113 2114/** 2115 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface. 2116 * 2117 * @file: Pointer to "struct file". 2118 * @buf: Pointer to buffer. 2119 * @count: Size of @buf. 2120 * @ppos: Unused. 2121 * 2122 * Returns bytes read on success, negative value otherwise. 2123 */ 2124static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 2125 loff_t *ppos) 2126{ 2127 return tomoyo_read_control(file, buf, count); 2128} 2129 2130/** 2131 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface. 2132 * 2133 * @file: Pointer to "struct file". 2134 * @buf: Pointer to buffer. 2135 * @count: Size of @buf. 2136 * @ppos: Unused. 2137 * 2138 * Returns @count on success, negative value otherwise. 2139 */ 2140static ssize_t tomoyo_write(struct file *file, const char __user *buf, 2141 size_t count, loff_t *ppos) 2142{ 2143 return tomoyo_write_control(file, buf, count); 2144} 2145 2146/* Operations for /sys/kernel/security/tomoyo/ interface. */ 2147static const struct file_operations tomoyo_operations = { 2148 .open = tomoyo_open, 2149 .release = tomoyo_release, 2150 .read = tomoyo_read, 2151 .write = tomoyo_write, 2152}; 2153 2154/** 2155 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory. 2156 * 2157 * @name: The name of the interface file. 2158 * @mode: The permission of the interface file. 2159 * @parent: The parent directory. 2160 * @key: Type of interface. 2161 * 2162 * Returns nothing. 2163 */ 2164static void __init tomoyo_create_entry(const char *name, const mode_t mode, 2165 struct dentry *parent, const u8 key) 2166{ 2167 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key, 2168 &tomoyo_operations); 2169} 2170 2171/** 2172 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface. 2173 * 2174 * Returns 0. 2175 */ 2176static int __init tomoyo_initerface_init(void) 2177{ 2178 struct dentry *tomoyo_dir; 2179 2180 /* Don't create securityfs entries unless registered. */ 2181 if (current_cred()->security != &tomoyo_kernel_domain) 2182 return 0; 2183 2184 tomoyo_dir = securityfs_create_dir("tomoyo", NULL); 2185 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir, 2186 TOMOYO_DOMAINPOLICY); 2187 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 2188 TOMOYO_EXCEPTIONPOLICY); 2189 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 2190 TOMOYO_SELFDOMAIN); 2191 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir, 2192 TOMOYO_DOMAIN_STATUS); 2193 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 2194 TOMOYO_PROCESS_STATUS); 2195 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 2196 TOMOYO_MEMINFO); 2197 tomoyo_create_entry("profile", 0600, tomoyo_dir, 2198 TOMOYO_PROFILE); 2199 tomoyo_create_entry("manager", 0600, tomoyo_dir, 2200 TOMOYO_MANAGER); 2201 tomoyo_create_entry("version", 0400, tomoyo_dir, 2202 TOMOYO_VERSION); 2203 return 0; 2204} 2205 2206fs_initcall(tomoyo_initerface_init); 2207