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