common.c revision cd7bec6ad80188394a8ea857ff1aa3512fc2282a
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 tomoyo_alloc(), so the caller must call tomoyo_free() 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 if (ptr->type & TOMOYO_ACL_DELETED) 846 continue; 847 switch (tomoyo_acl_type2(ptr)) { 848 struct tomoyo_single_path_acl_record *acl; 849 u32 perm; 850 u8 i; 851 case TOMOYO_TYPE_SINGLE_PATH_ACL: 852 acl = container_of(ptr, 853 struct tomoyo_single_path_acl_record, 854 head); 855 perm = acl->perm | (((u32) acl->perm_high) << 16); 856 for (i = 0; i < TOMOYO_MAX_SINGLE_PATH_OPERATION; i++) 857 if (perm & (1 << i)) 858 count++; 859 if (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 860 count -= 2; 861 break; 862 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 863 perm = container_of(ptr, 864 struct tomoyo_double_path_acl_record, 865 head)->perm; 866 for (i = 0; i < TOMOYO_MAX_DOUBLE_PATH_OPERATION; i++) 867 if (perm & (1 << i)) 868 count++; 869 break; 870 } 871 } 872 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 873 return true; 874 if (!domain->quota_warned) { 875 domain->quota_warned = true; 876 printk(KERN_WARNING "TOMOYO-WARNING: " 877 "Domain '%s' has so many ACLs to hold. " 878 "Stopped learning mode.\n", domain->domainname->name); 879 } 880 return false; 881} 882 883/** 884 * tomoyo_find_or_assign_new_profile - Create a new profile. 885 * 886 * @profile: Profile number to create. 887 * 888 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 889 */ 890static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned 891 int profile) 892{ 893 static DEFINE_MUTEX(lock); 894 struct tomoyo_profile *ptr = NULL; 895 int i; 896 897 if (profile >= TOMOYO_MAX_PROFILES) 898 return NULL; 899 mutex_lock(&lock); 900 ptr = tomoyo_profile_ptr[profile]; 901 if (ptr) 902 goto ok; 903 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); 904 if (!tomoyo_memory_ok(ptr)) { 905 kfree(ptr); 906 goto ok; 907 } 908 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 909 ptr->value[i] = tomoyo_control_array[i].current_value; 910 mb(); /* Avoid out-of-order execution. */ 911 tomoyo_profile_ptr[profile] = ptr; 912 ok: 913 mutex_unlock(&lock); 914 return ptr; 915} 916 917/** 918 * tomoyo_write_profile - Write to profile table. 919 * 920 * @head: Pointer to "struct tomoyo_io_buffer". 921 * 922 * Returns 0 on success, negative value otherwise. 923 */ 924static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 925{ 926 char *data = head->write_buf; 927 unsigned int i; 928 unsigned int value; 929 char *cp; 930 struct tomoyo_profile *profile; 931 unsigned long num; 932 933 cp = strchr(data, '-'); 934 if (cp) 935 *cp = '\0'; 936 if (strict_strtoul(data, 10, &num)) 937 return -EINVAL; 938 if (cp) 939 data = cp + 1; 940 profile = tomoyo_find_or_assign_new_profile(num); 941 if (!profile) 942 return -EINVAL; 943 cp = strchr(data, '='); 944 if (!cp) 945 return -EINVAL; 946 *cp = '\0'; 947 if (!strcmp(data, "COMMENT")) { 948 profile->comment = tomoyo_save_name(cp + 1); 949 return 0; 950 } 951 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 952 if (strcmp(data, tomoyo_control_array[i].keyword)) 953 continue; 954 if (sscanf(cp + 1, "%u", &value) != 1) { 955 int j; 956 const char **modes; 957 switch (i) { 958 case TOMOYO_VERBOSE: 959 modes = tomoyo_mode_2; 960 break; 961 default: 962 modes = tomoyo_mode_4; 963 break; 964 } 965 for (j = 0; j < 4; j++) { 966 if (strcmp(cp + 1, modes[j])) 967 continue; 968 value = j; 969 break; 970 } 971 if (j == 4) 972 return -EINVAL; 973 } else if (value > tomoyo_control_array[i].max_value) { 974 value = tomoyo_control_array[i].max_value; 975 } 976 profile->value[i] = value; 977 return 0; 978 } 979 return -EINVAL; 980} 981 982/** 983 * tomoyo_read_profile - Read from profile table. 984 * 985 * @head: Pointer to "struct tomoyo_io_buffer". 986 * 987 * Returns 0. 988 */ 989static int tomoyo_read_profile(struct tomoyo_io_buffer *head) 990{ 991 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; 992 int step; 993 994 if (head->read_eof) 995 return 0; 996 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; 997 step++) { 998 const u8 index = step / total; 999 u8 type = step % total; 1000 const struct tomoyo_profile *profile 1001 = tomoyo_profile_ptr[index]; 1002 head->read_step = step; 1003 if (!profile) 1004 continue; 1005 if (!type) { /* Print profile' comment tag. */ 1006 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", 1007 index, profile->comment ? 1008 profile->comment->name : "")) 1009 break; 1010 continue; 1011 } 1012 type--; 1013 if (type < TOMOYO_MAX_CONTROL_INDEX) { 1014 const unsigned int value = profile->value[type]; 1015 const char **modes = NULL; 1016 const char *keyword 1017 = tomoyo_control_array[type].keyword; 1018 switch (tomoyo_control_array[type].max_value) { 1019 case 3: 1020 modes = tomoyo_mode_4; 1021 break; 1022 case 1: 1023 modes = tomoyo_mode_2; 1024 break; 1025 } 1026 if (modes) { 1027 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index, 1028 keyword, modes[value])) 1029 break; 1030 } else { 1031 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index, 1032 keyword, value)) 1033 break; 1034 } 1035 } 1036 } 1037 if (step == TOMOYO_MAX_PROFILES * total) 1038 head->read_eof = true; 1039 return 0; 1040} 1041 1042/* 1043 * tomoyo_policy_manager_entry is a structure which is used for holding list of 1044 * domainnames or programs which are permitted to modify configuration via 1045 * /sys/kernel/security/tomoyo/ interface. 1046 * It has following fields. 1047 * 1048 * (1) "list" which is linked to tomoyo_policy_manager_list . 1049 * (2) "manager" is a domainname or a program's pathname. 1050 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false 1051 * otherwise. 1052 * (4) "is_deleted" is a bool which is true if marked as deleted, false 1053 * otherwise. 1054 */ 1055struct tomoyo_policy_manager_entry { 1056 struct list_head list; 1057 /* A path to program or a domainname. */ 1058 const struct tomoyo_path_info *manager; 1059 bool is_domain; /* True if manager is a domainname. */ 1060 bool is_deleted; /* True if this entry is deleted. */ 1061}; 1062 1063/* 1064 * tomoyo_policy_manager_list is used for holding list of domainnames or 1065 * programs which are permitted to modify configuration via 1066 * /sys/kernel/security/tomoyo/ interface. 1067 * 1068 * An entry is added by 1069 * 1070 * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \ 1071 * /sys/kernel/security/tomoyo/manager 1072 * (if you want to specify by a domainname) 1073 * 1074 * or 1075 * 1076 * # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager 1077 * (if you want to specify by a program's location) 1078 * 1079 * and is deleted by 1080 * 1081 * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \ 1082 * /sys/kernel/security/tomoyo/manager 1083 * 1084 * or 1085 * 1086 * # echo 'delete /usr/lib/ccs/editpolicy' > \ 1087 * /sys/kernel/security/tomoyo/manager 1088 * 1089 * and all entries are retrieved by 1090 * 1091 * # cat /sys/kernel/security/tomoyo/manager 1092 */ 1093static LIST_HEAD(tomoyo_policy_manager_list); 1094 1095/** 1096 * tomoyo_update_manager_entry - Add a manager entry. 1097 * 1098 * @manager: The path to manager or the domainnamme. 1099 * @is_delete: True if it is a delete request. 1100 * 1101 * Returns 0 on success, negative value otherwise. 1102 * 1103 * Caller holds tomoyo_read_lock(). 1104 */ 1105static int tomoyo_update_manager_entry(const char *manager, 1106 const bool is_delete) 1107{ 1108 struct tomoyo_policy_manager_entry *new_entry; 1109 struct tomoyo_policy_manager_entry *ptr; 1110 const struct tomoyo_path_info *saved_manager; 1111 int error = -ENOMEM; 1112 bool is_domain = false; 1113 1114 if (tomoyo_is_domain_def(manager)) { 1115 if (!tomoyo_is_correct_domain(manager, __func__)) 1116 return -EINVAL; 1117 is_domain = true; 1118 } else { 1119 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1120 return -EINVAL; 1121 } 1122 saved_manager = tomoyo_save_name(manager); 1123 if (!saved_manager) 1124 return -ENOMEM; 1125 new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); 1126 mutex_lock(&tomoyo_policy_lock); 1127 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1128 if (ptr->manager != saved_manager) 1129 continue; 1130 ptr->is_deleted = is_delete; 1131 error = 0; 1132 goto out; 1133 } 1134 if (is_delete) { 1135 error = -ENOENT; 1136 goto out; 1137 } 1138 if (!tomoyo_memory_ok(new_entry)) 1139 goto out; 1140 new_entry->manager = saved_manager; 1141 new_entry->is_domain = is_domain; 1142 list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list); 1143 new_entry = NULL; 1144 error = 0; 1145 out: 1146 mutex_unlock(&tomoyo_policy_lock); 1147 kfree(new_entry); 1148 return error; 1149} 1150 1151/** 1152 * tomoyo_write_manager_policy - Write manager policy. 1153 * 1154 * @head: Pointer to "struct tomoyo_io_buffer". 1155 * 1156 * Returns 0 on success, negative value otherwise. 1157 * 1158 * Caller holds tomoyo_read_lock(). 1159 */ 1160static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1161{ 1162 char *data = head->write_buf; 1163 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1164 1165 if (!strcmp(data, "manage_by_non_root")) { 1166 tomoyo_manage_by_non_root = !is_delete; 1167 return 0; 1168 } 1169 return tomoyo_update_manager_entry(data, is_delete); 1170} 1171 1172/** 1173 * tomoyo_read_manager_policy - Read manager policy. 1174 * 1175 * @head: Pointer to "struct tomoyo_io_buffer". 1176 * 1177 * Returns 0. 1178 * 1179 * Caller holds tomoyo_read_lock(). 1180 */ 1181static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1182{ 1183 struct list_head *pos; 1184 bool done = true; 1185 1186 if (head->read_eof) 1187 return 0; 1188 list_for_each_cookie(pos, head->read_var2, 1189 &tomoyo_policy_manager_list) { 1190 struct tomoyo_policy_manager_entry *ptr; 1191 ptr = list_entry(pos, struct tomoyo_policy_manager_entry, 1192 list); 1193 if (ptr->is_deleted) 1194 continue; 1195 done = tomoyo_io_printf(head, "%s\n", ptr->manager->name); 1196 if (!done) 1197 break; 1198 } 1199 head->read_eof = done; 1200 return 0; 1201} 1202 1203/** 1204 * tomoyo_is_policy_manager - Check whether the current process is a policy manager. 1205 * 1206 * Returns true if the current process is permitted to modify policy 1207 * via /sys/kernel/security/tomoyo/ interface. 1208 * 1209 * Caller holds tomoyo_read_lock(). 1210 */ 1211static bool tomoyo_is_policy_manager(void) 1212{ 1213 struct tomoyo_policy_manager_entry *ptr; 1214 const char *exe; 1215 const struct task_struct *task = current; 1216 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; 1217 bool found = false; 1218 1219 if (!tomoyo_policy_loaded) 1220 return true; 1221 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 1222 return false; 1223 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1224 if (!ptr->is_deleted && ptr->is_domain 1225 && !tomoyo_pathcmp(domainname, ptr->manager)) { 1226 found = true; 1227 break; 1228 } 1229 } 1230 if (found) 1231 return true; 1232 exe = tomoyo_get_exe(); 1233 if (!exe) 1234 return false; 1235 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) { 1236 if (!ptr->is_deleted && !ptr->is_domain 1237 && !strcmp(exe, ptr->manager->name)) { 1238 found = true; 1239 break; 1240 } 1241 } 1242 if (!found) { /* Reduce error messages. */ 1243 static pid_t last_pid; 1244 const pid_t pid = current->pid; 1245 if (last_pid != pid) { 1246 printk(KERN_WARNING "%s ( %s ) is not permitted to " 1247 "update policies.\n", domainname->name, exe); 1248 last_pid = pid; 1249 } 1250 } 1251 tomoyo_free(exe); 1252 return found; 1253} 1254 1255/** 1256 * tomoyo_is_select_one - Parse select command. 1257 * 1258 * @head: Pointer to "struct tomoyo_io_buffer". 1259 * @data: String to parse. 1260 * 1261 * Returns true on success, false otherwise. 1262 * 1263 * Caller holds tomoyo_read_lock(). 1264 */ 1265static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1266 const char *data) 1267{ 1268 unsigned int pid; 1269 struct tomoyo_domain_info *domain = NULL; 1270 1271 if (sscanf(data, "pid=%u", &pid) == 1) { 1272 struct task_struct *p; 1273 read_lock(&tasklist_lock); 1274 p = find_task_by_vpid(pid); 1275 if (p) 1276 domain = tomoyo_real_domain(p); 1277 read_unlock(&tasklist_lock); 1278 } else if (!strncmp(data, "domain=", 7)) { 1279 if (tomoyo_is_domain_def(data + 7)) 1280 domain = tomoyo_find_domain(data + 7); 1281 } else 1282 return false; 1283 head->write_var1 = domain; 1284 /* Accessing read_buf is safe because head->io_sem is held. */ 1285 if (!head->read_buf) 1286 return true; /* Do nothing if open(O_WRONLY). */ 1287 head->read_avail = 0; 1288 tomoyo_io_printf(head, "# select %s\n", data); 1289 head->read_single_domain = true; 1290 head->read_eof = !domain; 1291 if (domain) { 1292 struct tomoyo_domain_info *d; 1293 head->read_var1 = NULL; 1294 list_for_each_entry_rcu(d, &tomoyo_domain_list, list) { 1295 if (d == domain) 1296 break; 1297 head->read_var1 = &d->list; 1298 } 1299 head->read_var2 = NULL; 1300 head->read_bit = 0; 1301 head->read_step = 0; 1302 if (domain->is_deleted) 1303 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 1304 } 1305 return true; 1306} 1307 1308/** 1309 * tomoyo_delete_domain - Delete a domain. 1310 * 1311 * @domainname: The name of domain. 1312 * 1313 * Returns 0. 1314 * 1315 * Caller holds tomoyo_read_lock(). 1316 */ 1317static int tomoyo_delete_domain(char *domainname) 1318{ 1319 struct tomoyo_domain_info *domain; 1320 struct tomoyo_path_info name; 1321 1322 name.name = domainname; 1323 tomoyo_fill_path_info(&name); 1324 mutex_lock(&tomoyo_policy_lock); 1325 /* Is there an active domain? */ 1326 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1327 /* Never delete tomoyo_kernel_domain */ 1328 if (domain == &tomoyo_kernel_domain) 1329 continue; 1330 if (domain->is_deleted || 1331 tomoyo_pathcmp(domain->domainname, &name)) 1332 continue; 1333 domain->is_deleted = true; 1334 break; 1335 } 1336 mutex_unlock(&tomoyo_policy_lock); 1337 return 0; 1338} 1339 1340/** 1341 * tomoyo_write_domain_policy - Write domain policy. 1342 * 1343 * @head: Pointer to "struct tomoyo_io_buffer". 1344 * 1345 * Returns 0 on success, negative value otherwise. 1346 * 1347 * Caller holds tomoyo_read_lock(). 1348 */ 1349static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1350{ 1351 char *data = head->write_buf; 1352 struct tomoyo_domain_info *domain = head->write_var1; 1353 bool is_delete = false; 1354 bool is_select = false; 1355 unsigned int profile; 1356 1357 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) 1358 is_delete = true; 1359 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) 1360 is_select = true; 1361 if (is_select && tomoyo_is_select_one(head, data)) 1362 return 0; 1363 /* Don't allow updating policies by non manager programs. */ 1364 if (!tomoyo_is_policy_manager()) 1365 return -EPERM; 1366 if (tomoyo_is_domain_def(data)) { 1367 domain = NULL; 1368 if (is_delete) 1369 tomoyo_delete_domain(data); 1370 else if (is_select) 1371 domain = tomoyo_find_domain(data); 1372 else 1373 domain = tomoyo_find_or_assign_new_domain(data, 0); 1374 head->write_var1 = domain; 1375 return 0; 1376 } 1377 if (!domain) 1378 return -EINVAL; 1379 1380 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1 1381 && profile < TOMOYO_MAX_PROFILES) { 1382 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded) 1383 domain->profile = (u8) profile; 1384 return 0; 1385 } 1386 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1387 tomoyo_set_domain_flag(domain, is_delete, 1388 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ); 1389 return 0; 1390 } 1391 return tomoyo_write_file_policy(data, domain, is_delete); 1392} 1393 1394/** 1395 * tomoyo_print_single_path_acl - Print a single path ACL entry. 1396 * 1397 * @head: Pointer to "struct tomoyo_io_buffer". 1398 * @ptr: Pointer to "struct tomoyo_single_path_acl_record". 1399 * 1400 * Returns true on success, false otherwise. 1401 */ 1402static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head, 1403 struct tomoyo_single_path_acl_record * 1404 ptr) 1405{ 1406 int pos; 1407 u8 bit; 1408 const char *atmark = ""; 1409 const char *filename; 1410 const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16); 1411 1412 filename = ptr->filename->name; 1413 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION; 1414 bit++) { 1415 const char *msg; 1416 if (!(perm & (1 << bit))) 1417 continue; 1418 /* Print "read/write" instead of "read" and "write". */ 1419 if ((bit == TOMOYO_TYPE_READ_ACL || 1420 bit == TOMOYO_TYPE_WRITE_ACL) 1421 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))) 1422 continue; 1423 msg = tomoyo_sp2keyword(bit); 1424 pos = head->read_avail; 1425 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg, 1426 atmark, filename)) 1427 goto out; 1428 } 1429 head->read_bit = 0; 1430 return true; 1431 out: 1432 head->read_bit = bit; 1433 head->read_avail = pos; 1434 return false; 1435} 1436 1437/** 1438 * tomoyo_print_double_path_acl - Print a double path ACL entry. 1439 * 1440 * @head: Pointer to "struct tomoyo_io_buffer". 1441 * @ptr: Pointer to "struct tomoyo_double_path_acl_record". 1442 * 1443 * Returns true on success, false otherwise. 1444 */ 1445static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, 1446 struct tomoyo_double_path_acl_record * 1447 ptr) 1448{ 1449 int pos; 1450 const char *atmark1 = ""; 1451 const char *atmark2 = ""; 1452 const char *filename1; 1453 const char *filename2; 1454 const u8 perm = ptr->perm; 1455 u8 bit; 1456 1457 filename1 = ptr->filename1->name; 1458 filename2 = ptr->filename2->name; 1459 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION; 1460 bit++) { 1461 const char *msg; 1462 if (!(perm & (1 << bit))) 1463 continue; 1464 msg = tomoyo_dp2keyword(bit); 1465 pos = head->read_avail; 1466 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg, 1467 atmark1, filename1, atmark2, filename2)) 1468 goto out; 1469 } 1470 head->read_bit = 0; 1471 return true; 1472 out: 1473 head->read_bit = bit; 1474 head->read_avail = pos; 1475 return false; 1476} 1477 1478/** 1479 * tomoyo_print_entry - Print an ACL entry. 1480 * 1481 * @head: Pointer to "struct tomoyo_io_buffer". 1482 * @ptr: Pointer to an ACL entry. 1483 * 1484 * Returns true on success, false otherwise. 1485 */ 1486static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1487 struct tomoyo_acl_info *ptr) 1488{ 1489 const u8 acl_type = tomoyo_acl_type2(ptr); 1490 1491 if (acl_type & TOMOYO_ACL_DELETED) 1492 return true; 1493 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { 1494 struct tomoyo_single_path_acl_record *acl 1495 = container_of(ptr, 1496 struct tomoyo_single_path_acl_record, 1497 head); 1498 return tomoyo_print_single_path_acl(head, acl); 1499 } 1500 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) { 1501 struct tomoyo_double_path_acl_record *acl 1502 = container_of(ptr, 1503 struct tomoyo_double_path_acl_record, 1504 head); 1505 return tomoyo_print_double_path_acl(head, acl); 1506 } 1507 BUG(); /* This must not happen. */ 1508 return false; 1509} 1510 1511/** 1512 * tomoyo_read_domain_policy - Read domain policy. 1513 * 1514 * @head: Pointer to "struct tomoyo_io_buffer". 1515 * 1516 * Returns 0. 1517 * 1518 * Caller holds tomoyo_read_lock(). 1519 */ 1520static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1521{ 1522 struct list_head *dpos; 1523 struct list_head *apos; 1524 bool done = true; 1525 1526 if (head->read_eof) 1527 return 0; 1528 if (head->read_step == 0) 1529 head->read_step = 1; 1530 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { 1531 struct tomoyo_domain_info *domain; 1532 const char *quota_exceeded = ""; 1533 const char *transition_failed = ""; 1534 const char *ignore_global_allow_read = ""; 1535 domain = list_entry(dpos, struct tomoyo_domain_info, list); 1536 if (head->read_step != 1) 1537 goto acl_loop; 1538 if (domain->is_deleted && !head->read_single_domain) 1539 continue; 1540 /* Print domainname and flags. */ 1541 if (domain->quota_warned) 1542 quota_exceeded = "quota_exceeded\n"; 1543 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) 1544 transition_failed = "transition_failed\n"; 1545 if (domain->flags & 1546 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) 1547 ignore_global_allow_read 1548 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1549 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE 1550 "%u\n%s%s%s\n", 1551 domain->domainname->name, 1552 domain->profile, quota_exceeded, 1553 transition_failed, 1554 ignore_global_allow_read); 1555 if (!done) 1556 break; 1557 head->read_step = 2; 1558acl_loop: 1559 if (head->read_step == 3) 1560 goto tail_mark; 1561 /* Print ACL entries in the domain. */ 1562 list_for_each_cookie(apos, head->read_var2, 1563 &domain->acl_info_list) { 1564 struct tomoyo_acl_info *ptr 1565 = list_entry(apos, struct tomoyo_acl_info, 1566 list); 1567 done = tomoyo_print_entry(head, ptr); 1568 if (!done) 1569 break; 1570 } 1571 if (!done) 1572 break; 1573 head->read_step = 3; 1574tail_mark: 1575 done = tomoyo_io_printf(head, "\n"); 1576 if (!done) 1577 break; 1578 head->read_step = 1; 1579 if (head->read_single_domain) 1580 break; 1581 } 1582 head->read_eof = done; 1583 return 0; 1584} 1585 1586/** 1587 * tomoyo_write_domain_profile - Assign profile for specified domain. 1588 * 1589 * @head: Pointer to "struct tomoyo_io_buffer". 1590 * 1591 * Returns 0 on success, -EINVAL otherwise. 1592 * 1593 * This is equivalent to doing 1594 * 1595 * ( echo "select " $domainname; echo "use_profile " $profile ) | 1596 * /usr/lib/ccs/loadpolicy -d 1597 * 1598 * Caller holds tomoyo_read_lock(). 1599 */ 1600static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1601{ 1602 char *data = head->write_buf; 1603 char *cp = strchr(data, ' '); 1604 struct tomoyo_domain_info *domain; 1605 unsigned long profile; 1606 1607 if (!cp) 1608 return -EINVAL; 1609 *cp = '\0'; 1610 domain = tomoyo_find_domain(cp + 1); 1611 if (strict_strtoul(data, 10, &profile)) 1612 return -EINVAL; 1613 if (domain && profile < TOMOYO_MAX_PROFILES 1614 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)) 1615 domain->profile = (u8) profile; 1616 return 0; 1617} 1618 1619/** 1620 * tomoyo_read_domain_profile - Read only domainname and profile. 1621 * 1622 * @head: Pointer to "struct tomoyo_io_buffer". 1623 * 1624 * Returns list of profile number and domainname pairs. 1625 * 1626 * This is equivalent to doing 1627 * 1628 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy | 1629 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) 1630 * domainname = $0; } else if ( $1 == "use_profile" ) { 1631 * print $2 " " domainname; domainname = ""; } } ; ' 1632 * 1633 * Caller holds tomoyo_read_lock(). 1634 */ 1635static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1636{ 1637 struct list_head *pos; 1638 bool done = true; 1639 1640 if (head->read_eof) 1641 return 0; 1642 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { 1643 struct tomoyo_domain_info *domain; 1644 domain = list_entry(pos, struct tomoyo_domain_info, list); 1645 if (domain->is_deleted) 1646 continue; 1647 done = tomoyo_io_printf(head, "%u %s\n", domain->profile, 1648 domain->domainname->name); 1649 if (!done) 1650 break; 1651 } 1652 head->read_eof = done; 1653 return 0; 1654} 1655 1656/** 1657 * tomoyo_write_pid: Specify PID to obtain domainname. 1658 * 1659 * @head: Pointer to "struct tomoyo_io_buffer". 1660 * 1661 * Returns 0. 1662 */ 1663static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1664{ 1665 unsigned long pid; 1666 /* No error check. */ 1667 strict_strtoul(head->write_buf, 10, &pid); 1668 head->read_step = (int) pid; 1669 head->read_eof = false; 1670 return 0; 1671} 1672 1673/** 1674 * tomoyo_read_pid - Get domainname of the specified PID. 1675 * 1676 * @head: Pointer to "struct tomoyo_io_buffer". 1677 * 1678 * Returns the domainname which the specified PID is in on success, 1679 * empty string otherwise. 1680 * The PID is specified by tomoyo_write_pid() so that the user can obtain 1681 * using read()/write() interface rather than sysctl() interface. 1682 */ 1683static int tomoyo_read_pid(struct tomoyo_io_buffer *head) 1684{ 1685 if (head->read_avail == 0 && !head->read_eof) { 1686 const int pid = head->read_step; 1687 struct task_struct *p; 1688 struct tomoyo_domain_info *domain = NULL; 1689 read_lock(&tasklist_lock); 1690 p = find_task_by_vpid(pid); 1691 if (p) 1692 domain = tomoyo_real_domain(p); 1693 read_unlock(&tasklist_lock); 1694 if (domain) 1695 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1696 domain->domainname->name); 1697 head->read_eof = true; 1698 } 1699 return 0; 1700} 1701 1702/** 1703 * tomoyo_write_exception_policy - Write exception policy. 1704 * 1705 * @head: Pointer to "struct tomoyo_io_buffer". 1706 * 1707 * Returns 0 on success, negative value otherwise. 1708 * 1709 * Caller holds tomoyo_read_lock(). 1710 */ 1711static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1712{ 1713 char *data = head->write_buf; 1714 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE); 1715 1716 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN)) 1717 return tomoyo_write_domain_keeper_policy(data, false, 1718 is_delete); 1719 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN)) 1720 return tomoyo_write_domain_keeper_policy(data, true, is_delete); 1721 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN)) 1722 return tomoyo_write_domain_initializer_policy(data, false, 1723 is_delete); 1724 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN)) 1725 return tomoyo_write_domain_initializer_policy(data, true, 1726 is_delete); 1727 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS)) 1728 return tomoyo_write_alias_policy(data, is_delete); 1729 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ)) 1730 return tomoyo_write_globally_readable_policy(data, is_delete); 1731 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN)) 1732 return tomoyo_write_pattern_policy(data, is_delete); 1733 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) 1734 return tomoyo_write_no_rewrite_policy(data, is_delete); 1735 return -EINVAL; 1736} 1737 1738/** 1739 * tomoyo_read_exception_policy - Read exception policy. 1740 * 1741 * @head: Pointer to "struct tomoyo_io_buffer". 1742 * 1743 * Returns 0 on success, -EINVAL otherwise. 1744 * 1745 * Caller holds tomoyo_read_lock(). 1746 */ 1747static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1748{ 1749 if (!head->read_eof) { 1750 switch (head->read_step) { 1751 case 0: 1752 head->read_var2 = NULL; 1753 head->read_step = 1; 1754 case 1: 1755 if (!tomoyo_read_domain_keeper_policy(head)) 1756 break; 1757 head->read_var2 = NULL; 1758 head->read_step = 2; 1759 case 2: 1760 if (!tomoyo_read_globally_readable_policy(head)) 1761 break; 1762 head->read_var2 = NULL; 1763 head->read_step = 3; 1764 case 3: 1765 head->read_var2 = NULL; 1766 head->read_step = 4; 1767 case 4: 1768 if (!tomoyo_read_domain_initializer_policy(head)) 1769 break; 1770 head->read_var2 = NULL; 1771 head->read_step = 5; 1772 case 5: 1773 if (!tomoyo_read_alias_policy(head)) 1774 break; 1775 head->read_var2 = NULL; 1776 head->read_step = 6; 1777 case 6: 1778 head->read_var2 = NULL; 1779 head->read_step = 7; 1780 case 7: 1781 if (!tomoyo_read_file_pattern(head)) 1782 break; 1783 head->read_var2 = NULL; 1784 head->read_step = 8; 1785 case 8: 1786 if (!tomoyo_read_no_rewrite_policy(head)) 1787 break; 1788 head->read_var2 = NULL; 1789 head->read_step = 9; 1790 case 9: 1791 head->read_eof = true; 1792 break; 1793 default: 1794 return -EINVAL; 1795 } 1796 } 1797 return 0; 1798} 1799 1800/* path to policy loader */ 1801static const char *tomoyo_loader = "/sbin/tomoyo-init"; 1802 1803/** 1804 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 1805 * 1806 * Returns true if /sbin/tomoyo-init exists, false otherwise. 1807 */ 1808static bool tomoyo_policy_loader_exists(void) 1809{ 1810 /* 1811 * Don't activate MAC if the policy loader doesn't exist. 1812 * If the initrd includes /sbin/init but real-root-dev has not 1813 * mounted on / yet, activating MAC will block the system since 1814 * policies are not loaded yet. 1815 * Thus, let do_execve() call this function everytime. 1816 */ 1817 struct path path; 1818 1819 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) { 1820 printk(KERN_INFO "Not activating Mandatory Access Control now " 1821 "since %s doesn't exist.\n", tomoyo_loader); 1822 return false; 1823 } 1824 path_put(&path); 1825 return true; 1826} 1827 1828/** 1829 * tomoyo_load_policy - Run external policy loader to load policy. 1830 * 1831 * @filename: The program about to start. 1832 * 1833 * This function checks whether @filename is /sbin/init , and if so 1834 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init 1835 * and then continues invocation of /sbin/init. 1836 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and 1837 * writes to /sys/kernel/security/tomoyo/ interfaces. 1838 * 1839 * Returns nothing. 1840 */ 1841void tomoyo_load_policy(const char *filename) 1842{ 1843 char *argv[2]; 1844 char *envp[3]; 1845 1846 if (tomoyo_policy_loaded) 1847 return; 1848 /* 1849 * Check filename is /sbin/init or /sbin/tomoyo-start. 1850 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't 1851 * be passed. 1852 * You can create /sbin/tomoyo-start by 1853 * "ln -s /bin/true /sbin/tomoyo-start". 1854 */ 1855 if (strcmp(filename, "/sbin/init") && 1856 strcmp(filename, "/sbin/tomoyo-start")) 1857 return; 1858 if (!tomoyo_policy_loader_exists()) 1859 return; 1860 1861 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 1862 tomoyo_loader); 1863 argv[0] = (char *) tomoyo_loader; 1864 argv[1] = NULL; 1865 envp[0] = "HOME=/"; 1866 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 1867 envp[2] = NULL; 1868 call_usermodehelper(argv[0], argv, envp, 1); 1869 1870 printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n"); 1871 printk(KERN_INFO "Mandatory Access Control activated.\n"); 1872 tomoyo_policy_loaded = true; 1873 { /* Check all profiles currently assigned to domains are defined. */ 1874 struct tomoyo_domain_info *domain; 1875 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1876 const u8 profile = domain->profile; 1877 if (tomoyo_profile_ptr[profile]) 1878 continue; 1879 panic("Profile %u (used by '%s') not defined.\n", 1880 profile, domain->domainname->name); 1881 } 1882 } 1883} 1884 1885/** 1886 * tomoyo_read_version: Get version. 1887 * 1888 * @head: Pointer to "struct tomoyo_io_buffer". 1889 * 1890 * Returns version information. 1891 */ 1892static int tomoyo_read_version(struct tomoyo_io_buffer *head) 1893{ 1894 if (!head->read_eof) { 1895 tomoyo_io_printf(head, "2.2.0"); 1896 head->read_eof = true; 1897 } 1898 return 0; 1899} 1900 1901/** 1902 * tomoyo_read_self_domain - Get the current process's domainname. 1903 * 1904 * @head: Pointer to "struct tomoyo_io_buffer". 1905 * 1906 * Returns the current process's domainname. 1907 */ 1908static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head) 1909{ 1910 if (!head->read_eof) { 1911 /* 1912 * tomoyo_domain()->domainname != NULL 1913 * because every process belongs to a domain and 1914 * the domain's name cannot be NULL. 1915 */ 1916 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); 1917 head->read_eof = true; 1918 } 1919 return 0; 1920} 1921 1922/** 1923 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 1924 * 1925 * @type: Type of interface. 1926 * @file: Pointer to "struct file". 1927 * 1928 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 1929 * 1930 * Caller acquires tomoyo_read_lock(). 1931 */ 1932static int tomoyo_open_control(const u8 type, struct file *file) 1933{ 1934 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head)); 1935 1936 if (!head) 1937 return -ENOMEM; 1938 mutex_init(&head->io_sem); 1939 switch (type) { 1940 case TOMOYO_DOMAINPOLICY: 1941 /* /sys/kernel/security/tomoyo/domain_policy */ 1942 head->write = tomoyo_write_domain_policy; 1943 head->read = tomoyo_read_domain_policy; 1944 break; 1945 case TOMOYO_EXCEPTIONPOLICY: 1946 /* /sys/kernel/security/tomoyo/exception_policy */ 1947 head->write = tomoyo_write_exception_policy; 1948 head->read = tomoyo_read_exception_policy; 1949 break; 1950 case TOMOYO_SELFDOMAIN: 1951 /* /sys/kernel/security/tomoyo/self_domain */ 1952 head->read = tomoyo_read_self_domain; 1953 break; 1954 case TOMOYO_DOMAIN_STATUS: 1955 /* /sys/kernel/security/tomoyo/.domain_status */ 1956 head->write = tomoyo_write_domain_profile; 1957 head->read = tomoyo_read_domain_profile; 1958 break; 1959 case TOMOYO_PROCESS_STATUS: 1960 /* /sys/kernel/security/tomoyo/.process_status */ 1961 head->write = tomoyo_write_pid; 1962 head->read = tomoyo_read_pid; 1963 break; 1964 case TOMOYO_VERSION: 1965 /* /sys/kernel/security/tomoyo/version */ 1966 head->read = tomoyo_read_version; 1967 head->readbuf_size = 128; 1968 break; 1969 case TOMOYO_MEMINFO: 1970 /* /sys/kernel/security/tomoyo/meminfo */ 1971 head->write = tomoyo_write_memory_quota; 1972 head->read = tomoyo_read_memory_counter; 1973 head->readbuf_size = 512; 1974 break; 1975 case TOMOYO_PROFILE: 1976 /* /sys/kernel/security/tomoyo/profile */ 1977 head->write = tomoyo_write_profile; 1978 head->read = tomoyo_read_profile; 1979 break; 1980 case TOMOYO_MANAGER: 1981 /* /sys/kernel/security/tomoyo/manager */ 1982 head->write = tomoyo_write_manager_policy; 1983 head->read = tomoyo_read_manager_policy; 1984 break; 1985 } 1986 if (!(file->f_mode & FMODE_READ)) { 1987 /* 1988 * No need to allocate read_buf since it is not opened 1989 * for reading. 1990 */ 1991 head->read = NULL; 1992 } else { 1993 if (!head->readbuf_size) 1994 head->readbuf_size = 4096 * 2; 1995 head->read_buf = tomoyo_alloc(head->readbuf_size); 1996 if (!head->read_buf) { 1997 tomoyo_free(head); 1998 return -ENOMEM; 1999 } 2000 } 2001 if (!(file->f_mode & FMODE_WRITE)) { 2002 /* 2003 * No need to allocate write_buf since it is not opened 2004 * for writing. 2005 */ 2006 head->write = NULL; 2007 } else if (head->write) { 2008 head->writebuf_size = 4096 * 2; 2009 head->write_buf = tomoyo_alloc(head->writebuf_size); 2010 if (!head->write_buf) { 2011 tomoyo_free(head->read_buf); 2012 tomoyo_free(head); 2013 return -ENOMEM; 2014 } 2015 } 2016 head->reader_idx = tomoyo_read_lock(); 2017 file->private_data = head; 2018 /* 2019 * Call the handler now if the file is 2020 * /sys/kernel/security/tomoyo/self_domain 2021 * so that the user can use 2022 * cat < /sys/kernel/security/tomoyo/self_domain" 2023 * to know the current process's domainname. 2024 */ 2025 if (type == TOMOYO_SELFDOMAIN) 2026 tomoyo_read_control(file, NULL, 0); 2027 return 0; 2028} 2029 2030/** 2031 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2032 * 2033 * @file: Pointer to "struct file". 2034 * @buffer: Poiner to buffer to write to. 2035 * @buffer_len: Size of @buffer. 2036 * 2037 * Returns bytes read on success, negative value otherwise. 2038 * 2039 * Caller holds tomoyo_read_lock(). 2040 */ 2041static int tomoyo_read_control(struct file *file, char __user *buffer, 2042 const int buffer_len) 2043{ 2044 int len = 0; 2045 struct tomoyo_io_buffer *head = file->private_data; 2046 char *cp; 2047 2048 if (!head->read) 2049 return -ENOSYS; 2050 if (mutex_lock_interruptible(&head->io_sem)) 2051 return -EINTR; 2052 /* Call the policy handler. */ 2053 len = head->read(head); 2054 if (len < 0) 2055 goto out; 2056 /* Write to buffer. */ 2057 len = head->read_avail; 2058 if (len > buffer_len) 2059 len = buffer_len; 2060 if (!len) 2061 goto out; 2062 /* head->read_buf changes by some functions. */ 2063 cp = head->read_buf; 2064 if (copy_to_user(buffer, cp, len)) { 2065 len = -EFAULT; 2066 goto out; 2067 } 2068 head->read_avail -= len; 2069 memmove(cp, cp + len, head->read_avail); 2070 out: 2071 mutex_unlock(&head->io_sem); 2072 return len; 2073} 2074 2075/** 2076 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2077 * 2078 * @file: Pointer to "struct file". 2079 * @buffer: Pointer to buffer to read from. 2080 * @buffer_len: Size of @buffer. 2081 * 2082 * Returns @buffer_len on success, negative value otherwise. 2083 * 2084 * Caller holds tomoyo_read_lock(). 2085 */ 2086static int tomoyo_write_control(struct file *file, const char __user *buffer, 2087 const int buffer_len) 2088{ 2089 struct tomoyo_io_buffer *head = file->private_data; 2090 int error = buffer_len; 2091 int avail_len = buffer_len; 2092 char *cp0 = head->write_buf; 2093 2094 if (!head->write) 2095 return -ENOSYS; 2096 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2097 return -EFAULT; 2098 /* Don't allow updating policies by non manager programs. */ 2099 if (head->write != tomoyo_write_pid && 2100 head->write != tomoyo_write_domain_policy && 2101 !tomoyo_is_policy_manager()) 2102 return -EPERM; 2103 if (mutex_lock_interruptible(&head->io_sem)) 2104 return -EINTR; 2105 /* Read a line and dispatch it to the policy handler. */ 2106 while (avail_len > 0) { 2107 char c; 2108 if (head->write_avail >= head->writebuf_size - 1) { 2109 error = -ENOMEM; 2110 break; 2111 } else if (get_user(c, buffer)) { 2112 error = -EFAULT; 2113 break; 2114 } 2115 buffer++; 2116 avail_len--; 2117 cp0[head->write_avail++] = c; 2118 if (c != '\n') 2119 continue; 2120 cp0[head->write_avail - 1] = '\0'; 2121 head->write_avail = 0; 2122 tomoyo_normalize_line(cp0); 2123 head->write(head); 2124 } 2125 mutex_unlock(&head->io_sem); 2126 return error; 2127} 2128 2129/** 2130 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2131 * 2132 * @file: Pointer to "struct file". 2133 * 2134 * Releases memory and returns 0. 2135 * 2136 * Caller looses tomoyo_read_lock(). 2137 */ 2138static int tomoyo_close_control(struct file *file) 2139{ 2140 struct tomoyo_io_buffer *head = file->private_data; 2141 2142 tomoyo_read_unlock(head->reader_idx); 2143 /* Release memory used for policy I/O. */ 2144 tomoyo_free(head->read_buf); 2145 head->read_buf = NULL; 2146 tomoyo_free(head->write_buf); 2147 head->write_buf = NULL; 2148 tomoyo_free(head); 2149 head = NULL; 2150 file->private_data = NULL; 2151 return 0; 2152} 2153 2154/** 2155 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2156 * 2157 * @inode: Pointer to "struct inode". 2158 * @file: Pointer to "struct file". 2159 * 2160 * Returns 0 on success, negative value otherwise. 2161 */ 2162static int tomoyo_open(struct inode *inode, struct file *file) 2163{ 2164 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private) 2165 - ((u8 *) NULL); 2166 return tomoyo_open_control(key, file); 2167} 2168 2169/** 2170 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface. 2171 * 2172 * @inode: Pointer to "struct inode". 2173 * @file: Pointer to "struct file". 2174 * 2175 * Returns 0 on success, negative value otherwise. 2176 */ 2177static int tomoyo_release(struct inode *inode, struct file *file) 2178{ 2179 return tomoyo_close_control(file); 2180} 2181 2182/** 2183 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface. 2184 * 2185 * @file: Pointer to "struct file". 2186 * @buf: Pointer to buffer. 2187 * @count: Size of @buf. 2188 * @ppos: Unused. 2189 * 2190 * Returns bytes read on success, negative value otherwise. 2191 */ 2192static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 2193 loff_t *ppos) 2194{ 2195 return tomoyo_read_control(file, buf, count); 2196} 2197 2198/** 2199 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface. 2200 * 2201 * @file: Pointer to "struct file". 2202 * @buf: Pointer to buffer. 2203 * @count: Size of @buf. 2204 * @ppos: Unused. 2205 * 2206 * Returns @count on success, negative value otherwise. 2207 */ 2208static ssize_t tomoyo_write(struct file *file, const char __user *buf, 2209 size_t count, loff_t *ppos) 2210{ 2211 return tomoyo_write_control(file, buf, count); 2212} 2213 2214/* 2215 * tomoyo_operations is a "struct file_operations" which is used for handling 2216 * /sys/kernel/security/tomoyo/ interface. 2217 * 2218 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR). 2219 * See tomoyo_io_buffer for internals. 2220 */ 2221static const struct file_operations tomoyo_operations = { 2222 .open = tomoyo_open, 2223 .release = tomoyo_release, 2224 .read = tomoyo_read, 2225 .write = tomoyo_write, 2226}; 2227 2228/** 2229 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory. 2230 * 2231 * @name: The name of the interface file. 2232 * @mode: The permission of the interface file. 2233 * @parent: The parent directory. 2234 * @key: Type of interface. 2235 * 2236 * Returns nothing. 2237 */ 2238static void __init tomoyo_create_entry(const char *name, const mode_t mode, 2239 struct dentry *parent, const u8 key) 2240{ 2241 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key, 2242 &tomoyo_operations); 2243} 2244 2245/** 2246 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface. 2247 * 2248 * Returns 0. 2249 */ 2250static int __init tomoyo_initerface_init(void) 2251{ 2252 struct dentry *tomoyo_dir; 2253 2254 /* Don't create securityfs entries unless registered. */ 2255 if (current_cred()->security != &tomoyo_kernel_domain) 2256 return 0; 2257 2258 tomoyo_dir = securityfs_create_dir("tomoyo", NULL); 2259 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir, 2260 TOMOYO_DOMAINPOLICY); 2261 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 2262 TOMOYO_EXCEPTIONPOLICY); 2263 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 2264 TOMOYO_SELFDOMAIN); 2265 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir, 2266 TOMOYO_DOMAIN_STATUS); 2267 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 2268 TOMOYO_PROCESS_STATUS); 2269 tomoyo_create_entry("meminfo", 0600, tomoyo_dir, 2270 TOMOYO_MEMINFO); 2271 tomoyo_create_entry("profile", 0600, tomoyo_dir, 2272 TOMOYO_PROFILE); 2273 tomoyo_create_entry("manager", 0600, tomoyo_dir, 2274 TOMOYO_MANAGER); 2275 tomoyo_create_entry("version", 0400, tomoyo_dir, 2276 TOMOYO_VERSION); 2277 return 0; 2278} 2279 2280fs_initcall(tomoyo_initerface_init); 2281