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