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