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