TOMOYO: Add interactive enforcing mode.
[linux-2.6-block.git] / security / tomoyo / common.c
CommitLineData
9590837b
KT
1/*
2 * security/tomoyo/common.c
3 *
4 * Common functions for TOMOYO.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
39826a1e 8 * Version: 2.2.0 2009/04/01
9590837b
KT
9 *
10 */
11
12#include <linux/uaccess.h>
5a0e3ad6 13#include <linux/slab.h>
9590837b
KT
14#include <linux/security.h>
15#include <linux/hardirq.h>
9590837b 16#include "common.h"
9590837b 17
f737d95d
TH
18/* Lock for protecting policy. */
19DEFINE_MUTEX(tomoyo_policy_lock);
20
9590837b
KT
21/* Has loading policy done? */
22bool tomoyo_policy_loaded;
23
24/* String table for functionality that takes 4 modes. */
25static const char *tomoyo_mode_4[4] = {
26 "disabled", "learning", "permissive", "enforcing"
27};
28/* String table for functionality that takes 2 modes. */
29static const char *tomoyo_mode_2[4] = {
30 "disabled", "enabled", "enabled", "enabled"
31};
32
c3fa109a
TH
33/*
34 * tomoyo_control_array is a static data which contains
35 *
36 * (1) functionality name used by /sys/kernel/security/tomoyo/profile .
37 * (2) initial values for "struct tomoyo_profile".
38 * (3) max values for "struct tomoyo_profile".
39 */
9590837b
KT
40static struct {
41 const char *keyword;
42 unsigned int current_value;
43 const unsigned int max_value;
44} tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = {
45 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
46 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX },
47 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
48};
49
c3fa109a
TH
50/*
51 * tomoyo_profile is a structure which is used for holding the mode of access
52 * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
53 * An administrator can define up to 256 profiles.
54 * The ->profile of "struct tomoyo_domain_info" is used for remembering
55 * the profile's number (0 - 255) assigned to that domain.
56 */
9590837b
KT
57static struct tomoyo_profile {
58 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
59 const struct tomoyo_path_info *comment;
60} *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
61
62/* Permit policy management by non-root user? */
63static bool tomoyo_manage_by_non_root;
64
65/* Utility functions. */
66
67/* Open operation for /sys/kernel/security/tomoyo/ interface. */
68static int tomoyo_open_control(const u8 type, struct file *file);
69/* Close /sys/kernel/security/tomoyo/ interface. */
70static int tomoyo_close_control(struct file *file);
71/* Read operation for /sys/kernel/security/tomoyo/ interface. */
72static int tomoyo_read_control(struct file *file, char __user *buffer,
73 const int buffer_len);
74/* Write operation for /sys/kernel/security/tomoyo/ interface. */
75static int tomoyo_write_control(struct file *file, const char __user *buffer,
76 const int buffer_len);
17fcfbd9
TH
77/* Check whether the domain has too many ACL entries to hold. */
78static bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
9590837b 79
7762fbff
TH
80/**
81 * tomoyo_parse_name_union - Parse a tomoyo_name_union.
82 *
83 * @filename: Name or name group.
84 * @ptr: Pointer to "struct tomoyo_name_union".
85 *
86 * Returns true on success, false otherwise.
87 */
88bool tomoyo_parse_name_union(const char *filename,
89 struct tomoyo_name_union *ptr)
90{
91 if (!tomoyo_is_correct_path(filename, 0, 0, 0))
92 return false;
93 if (filename[0] == '@') {
94 ptr->group = tomoyo_get_path_group(filename + 1);
95 ptr->is_group = true;
96 return ptr->group != NULL;
97 }
98 ptr->filename = tomoyo_get_name(filename);
99 ptr->is_group = false;
100 return ptr->filename != NULL;
101}
102
103/**
104 * tomoyo_print_name_union - Print a tomoyo_name_union.
105 *
106 * @head: Pointer to "struct tomoyo_io_buffer".
107 * @ptr: Pointer to "struct tomoyo_name_union".
108 *
109 * Returns true on success, false otherwise.
110 */
111static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head,
112 const struct tomoyo_name_union *ptr)
113{
114 int pos = head->read_avail;
115 if (pos && head->read_buf[pos - 1] == ' ')
116 head->read_avail--;
117 if (ptr->is_group)
118 return tomoyo_io_printf(head, " @%s",
119 ptr->group->group_name->name);
120 return tomoyo_io_printf(head, " %s", ptr->filename->name);
121}
122
4c3e9e2d
TH
123/**
124 * tomoyo_parse_ulong - Parse an "unsigned long" value.
125 *
126 * @result: Pointer to "unsigned long".
127 * @str: Pointer to string to parse.
128 *
129 * Returns value type on success, 0 otherwise.
130 *
131 * The @src is updated to point the first character after the value
132 * on success.
133 */
134u8 tomoyo_parse_ulong(unsigned long *result, char **str)
135{
136 const char *cp = *str;
137 char *ep;
138 int base = 10;
139 if (*cp == '0') {
140 char c = *(cp + 1);
141 if (c == 'x' || c == 'X') {
142 base = 16;
143 cp += 2;
144 } else if (c >= '0' && c <= '7') {
145 base = 8;
146 cp++;
147 }
148 }
149 *result = simple_strtoul(cp, &ep, base);
150 if (cp == ep)
151 return 0;
152 *str = ep;
153 switch (base) {
154 case 16:
155 return TOMOYO_VALUE_TYPE_HEXADECIMAL;
156 case 8:
157 return TOMOYO_VALUE_TYPE_OCTAL;
158 default:
159 return TOMOYO_VALUE_TYPE_DECIMAL;
160 }
161}
162
163/**
164 * tomoyo_print_ulong - Print an "unsigned long" value.
165 *
166 * @buffer: Pointer to buffer.
167 * @buffer_len: Size of @buffer.
168 * @value: An "unsigned long" value.
169 * @type: Type of @value.
170 *
171 * Returns nothing.
172 */
173void tomoyo_print_ulong(char *buffer, const int buffer_len,
174 const unsigned long value, const u8 type)
175{
176 if (type == TOMOYO_VALUE_TYPE_DECIMAL)
177 snprintf(buffer, buffer_len, "%lu", value);
178 else if (type == TOMOYO_VALUE_TYPE_OCTAL)
179 snprintf(buffer, buffer_len, "0%lo", value);
180 else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL)
181 snprintf(buffer, buffer_len, "0x%lX", value);
182 else
183 snprintf(buffer, buffer_len, "type(%u)", type);
184}
185
186/**
187 * tomoyo_print_number_union - Print a tomoyo_number_union.
188 *
189 * @head: Pointer to "struct tomoyo_io_buffer".
190 * @ptr: Pointer to "struct tomoyo_number_union".
191 *
192 * Returns true on success, false otherwise.
193 */
194bool tomoyo_print_number_union(struct tomoyo_io_buffer *head,
195 const struct tomoyo_number_union *ptr)
196{
197 unsigned long min;
198 unsigned long max;
199 u8 min_type;
200 u8 max_type;
201 if (!tomoyo_io_printf(head, " "))
202 return false;
203 if (ptr->is_group)
204 return tomoyo_io_printf(head, "@%s",
205 ptr->group->group_name->name);
206 min_type = ptr->min_type;
207 max_type = ptr->max_type;
208 min = ptr->values[0];
209 max = ptr->values[1];
210 switch (min_type) {
211 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
212 if (!tomoyo_io_printf(head, "0x%lX", min))
213 return false;
214 break;
215 case TOMOYO_VALUE_TYPE_OCTAL:
216 if (!tomoyo_io_printf(head, "0%lo", min))
217 return false;
218 break;
219 default:
220 if (!tomoyo_io_printf(head, "%lu", min))
221 return false;
222 break;
223 }
224 if (min == max && min_type == max_type)
225 return true;
226 switch (max_type) {
227 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
228 return tomoyo_io_printf(head, "-0x%lX", max);
229 case TOMOYO_VALUE_TYPE_OCTAL:
230 return tomoyo_io_printf(head, "-0%lo", max);
231 default:
232 return tomoyo_io_printf(head, "-%lu", max);
233 }
234}
235
236/**
237 * tomoyo_parse_number_union - Parse a tomoyo_number_union.
238 *
239 * @data: Number or number range or number group.
240 * @ptr: Pointer to "struct tomoyo_number_union".
241 *
242 * Returns true on success, false otherwise.
243 */
244bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
245{
246 u8 type;
247 unsigned long v;
248 memset(num, 0, sizeof(*num));
249 if (data[0] == '@') {
250 if (!tomoyo_is_correct_path(data, 0, 0, 0))
251 return false;
252 num->group = tomoyo_get_number_group(data + 1);
253 num->is_group = true;
254 return num->group != NULL;
255 }
256 type = tomoyo_parse_ulong(&v, &data);
257 if (!type)
258 return false;
259 num->values[0] = v;
260 num->min_type = type;
261 if (!*data) {
262 num->values[1] = v;
263 num->max_type = type;
264 return true;
265 }
266 if (*data++ != '-')
267 return false;
268 type = tomoyo_parse_ulong(&v, &data);
269 if (!type || *data)
270 return false;
271 num->values[1] = v;
272 num->max_type = type;
273 return true;
274}
275
9590837b
KT
276/**
277 * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
278 *
279 * @str: Pointer to the string.
280 *
281 * Returns true if @str is a \ooo style octal value, false otherwise.
282 *
283 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
284 * This function verifies that \ooo is in valid range.
285 */
286static inline bool tomoyo_is_byte_range(const char *str)
287{
288 return *str >= '0' && *str++ <= '3' &&
289 *str >= '0' && *str++ <= '7' &&
290 *str >= '0' && *str <= '7';
291}
292
293/**
294 * tomoyo_is_alphabet_char - Check whether the character is an alphabet.
295 *
296 * @c: The character to check.
297 *
298 * Returns true if @c is an alphabet character, false otherwise.
299 */
300static inline bool tomoyo_is_alphabet_char(const char c)
301{
302 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
303}
304
305/**
306 * tomoyo_make_byte - Make byte value from three octal characters.
307 *
308 * @c1: The first character.
309 * @c2: The second character.
310 * @c3: The third character.
311 *
312 * Returns byte value.
313 */
314static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
315{
316 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
317}
318
319/**
320 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
321 *
322 * @src: Pointer to pointer to the string.
323 * @find: Pointer to the keyword.
324 *
325 * Returns true if @src starts with @find, false otherwise.
326 *
327 * The @src is updated to point the first character after the @find
328 * if @src starts with @find.
329 */
330static bool tomoyo_str_starts(char **src, const char *find)
331{
332 const int len = strlen(find);
333 char *tmp = *src;
334
335 if (strncmp(tmp, find, len))
336 return false;
337 tmp += len;
338 *src = tmp;
339 return true;
340}
341
342/**
343 * tomoyo_normalize_line - Format string.
344 *
345 * @buffer: The line to normalize.
346 *
347 * Leading and trailing whitespaces are removed.
348 * Multiple whitespaces are packed into single space.
349 *
350 * Returns nothing.
351 */
352static void tomoyo_normalize_line(unsigned char *buffer)
353{
354 unsigned char *sp = buffer;
355 unsigned char *dp = buffer;
356 bool first = true;
357
358 while (tomoyo_is_invalid(*sp))
359 sp++;
360 while (*sp) {
361 if (!first)
362 *dp++ = ' ';
363 first = false;
364 while (tomoyo_is_valid(*sp))
365 *dp++ = *sp++;
366 while (tomoyo_is_invalid(*sp))
367 sp++;
368 }
369 *dp = '\0';
370}
371
7762fbff
TH
372/**
373 * tomoyo_tokenize - Tokenize string.
374 *
375 * @buffer: The line to tokenize.
376 * @w: Pointer to "char *".
377 * @size: Sizeof @w .
378 *
379 * Returns true on success, false otherwise.
380 */
381bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
382{
383 int count = size / sizeof(char *);
384 int i;
385 for (i = 0; i < count; i++)
386 w[i] = "";
387 for (i = 0; i < count; i++) {
388 char *cp = strchr(buffer, ' ');
389 if (cp)
390 *cp = '\0';
391 w[i] = buffer;
392 if (!cp)
393 break;
394 buffer = cp + 1;
395 }
396 return i < count || !*buffer;
397}
398
9590837b
KT
399/**
400 * tomoyo_is_correct_path - Validate a pathname.
401 * @filename: The pathname to check.
402 * @start_type: Should the pathname start with '/'?
403 * 1 = must / -1 = must not / 0 = don't care
404 * @pattern_type: Can the pathname contain a wildcard?
405 * 1 = must / -1 = must not / 0 = don't care
406 * @end_type: Should the pathname end with '/'?
407 * 1 = must / -1 = must not / 0 = don't care
9590837b
KT
408 *
409 * Check whether the given filename follows the naming rules.
410 * Returns true if @filename follows the naming rules, false otherwise.
411 */
412bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
17080008 413 const s8 pattern_type, const s8 end_type)
9590837b 414{
7539cf4b
TH
415 const char *const start = filename;
416 bool in_repetition = false;
9590837b
KT
417 bool contains_pattern = false;
418 unsigned char c;
419 unsigned char d;
420 unsigned char e;
9590837b
KT
421
422 if (!filename)
423 goto out;
424 c = *filename;
425 if (start_type == 1) { /* Must start with '/' */
426 if (c != '/')
427 goto out;
428 } else if (start_type == -1) { /* Must not start with '/' */
429 if (c == '/')
430 goto out;
431 }
432 if (c)
433 c = *(filename + strlen(filename) - 1);
434 if (end_type == 1) { /* Must end with '/' */
435 if (c != '/')
436 goto out;
437 } else if (end_type == -1) { /* Must not end with '/' */
438 if (c == '/')
439 goto out;
440 }
7539cf4b
TH
441 while (1) {
442 c = *filename++;
443 if (!c)
444 break;
9590837b 445 if (c == '\\') {
7539cf4b
TH
446 c = *filename++;
447 switch (c) {
9590837b
KT
448 case '\\': /* "\\" */
449 continue;
450 case '$': /* "\$" */
451 case '+': /* "\+" */
452 case '?': /* "\?" */
453 case '*': /* "\*" */
454 case '@': /* "\@" */
455 case 'x': /* "\x" */
456 case 'X': /* "\X" */
457 case 'a': /* "\a" */
458 case 'A': /* "\A" */
459 case '-': /* "\-" */
460 if (pattern_type == -1)
461 break; /* Must not contain pattern */
462 contains_pattern = true;
463 continue;
7539cf4b
TH
464 case '{': /* "/\{" */
465 if (filename - 3 < start ||
466 *(filename - 3) != '/')
467 break;
468 if (pattern_type == -1)
469 break; /* Must not contain pattern */
470 contains_pattern = true;
471 in_repetition = true;
472 continue;
473 case '}': /* "\}/" */
474 if (*filename != '/')
475 break;
476 if (!in_repetition)
477 break;
478 in_repetition = false;
479 continue;
9590837b
KT
480 case '0': /* "\ooo" */
481 case '1':
482 case '2':
483 case '3':
484 d = *filename++;
485 if (d < '0' || d > '7')
486 break;
487 e = *filename++;
488 if (e < '0' || e > '7')
489 break;
490 c = tomoyo_make_byte(c, d, e);
491 if (tomoyo_is_invalid(c))
492 continue; /* pattern is not \000 */
493 }
494 goto out;
7539cf4b
TH
495 } else if (in_repetition && c == '/') {
496 goto out;
9590837b
KT
497 } else if (tomoyo_is_invalid(c)) {
498 goto out;
499 }
500 }
501 if (pattern_type == 1) { /* Must contain pattern */
502 if (!contains_pattern)
503 goto out;
504 }
7539cf4b
TH
505 if (in_repetition)
506 goto out;
9590837b
KT
507 return true;
508 out:
9590837b
KT
509 return false;
510}
511
512/**
513 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules.
514 * @domainname: The domainname to check.
9590837b
KT
515 *
516 * Returns true if @domainname follows the naming rules, false otherwise.
517 */
17080008 518bool tomoyo_is_correct_domain(const unsigned char *domainname)
9590837b
KT
519{
520 unsigned char c;
521 unsigned char d;
522 unsigned char e;
9590837b
KT
523
524 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
525 TOMOYO_ROOT_NAME_LEN))
526 goto out;
527 domainname += TOMOYO_ROOT_NAME_LEN;
528 if (!*domainname)
529 return true;
530 do {
531 if (*domainname++ != ' ')
532 goto out;
533 if (*domainname++ != '/')
534 goto out;
535 while ((c = *domainname) != '\0' && c != ' ') {
536 domainname++;
537 if (c == '\\') {
538 c = *domainname++;
539 switch ((c)) {
540 case '\\': /* "\\" */
541 continue;
542 case '0': /* "\ooo" */
543 case '1':
544 case '2':
545 case '3':
546 d = *domainname++;
547 if (d < '0' || d > '7')
548 break;
549 e = *domainname++;
550 if (e < '0' || e > '7')
551 break;
552 c = tomoyo_make_byte(c, d, e);
553 if (tomoyo_is_invalid(c))
554 /* pattern is not \000 */
555 continue;
556 }
557 goto out;
558 } else if (tomoyo_is_invalid(c)) {
559 goto out;
560 }
561 }
562 } while (*domainname);
563 return true;
564 out:
9590837b
KT
565 return false;
566}
567
568/**
569 * tomoyo_is_domain_def - Check whether the given token can be a domainname.
570 *
571 * @buffer: The token to check.
572 *
573 * Returns true if @buffer possibly be a domainname, false otherwise.
574 */
575bool tomoyo_is_domain_def(const unsigned char *buffer)
576{
577 return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN);
578}
579
580/**
581 * tomoyo_find_domain - Find a domain by the given name.
582 *
583 * @domainname: The domainname to find.
584 *
9590837b 585 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
fdb8ebb7
TH
586 *
587 * Caller holds tomoyo_read_lock().
9590837b
KT
588 */
589struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
590{
591 struct tomoyo_domain_info *domain;
592 struct tomoyo_path_info name;
593
594 name.name = domainname;
595 tomoyo_fill_path_info(&name);
fdb8ebb7 596 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
9590837b
KT
597 if (!domain->is_deleted &&
598 !tomoyo_pathcmp(&name, domain->domainname))
599 return domain;
600 }
601 return NULL;
602}
603
9590837b
KT
604/**
605 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
606 *
607 * @filename: The string to evaluate.
608 *
609 * Returns the initial length without a pattern in @filename.
610 */
611static int tomoyo_const_part_length(const char *filename)
612{
613 char c;
614 int len = 0;
615
616 if (!filename)
617 return 0;
618 while ((c = *filename++) != '\0') {
619 if (c != '\\') {
620 len++;
621 continue;
622 }
623 c = *filename++;
624 switch (c) {
625 case '\\': /* "\\" */
626 len += 2;
627 continue;
628 case '0': /* "\ooo" */
629 case '1':
630 case '2':
631 case '3':
632 c = *filename++;
633 if (c < '0' || c > '7')
634 break;
635 c = *filename++;
636 if (c < '0' || c > '7')
637 break;
638 len += 4;
639 continue;
640 }
641 break;
642 }
643 return len;
644}
645
646/**
647 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
648 *
649 * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
650 *
651 * The caller sets "struct tomoyo_path_info"->name.
652 */
653void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
654{
655 const char *name = ptr->name;
656 const int len = strlen(name);
657
9590837b
KT
658 ptr->const_len = tomoyo_const_part_length(name);
659 ptr->is_dir = len && (name[len - 1] == '/');
660 ptr->is_patterned = (ptr->const_len < len);
661 ptr->hash = full_name_hash(name, len);
9590837b
KT
662}
663
664/**
7539cf4b 665 * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
9590837b
KT
666 * and "\-" pattern.
667 *
668 * @filename: The start of string to check.
669 * @filename_end: The end of string to check.
670 * @pattern: The start of pattern to compare.
671 * @pattern_end: The end of pattern to compare.
672 *
673 * Returns true if @filename matches @pattern, false otherwise.
674 */
7539cf4b
TH
675static bool tomoyo_file_matches_pattern2(const char *filename,
676 const char *filename_end,
677 const char *pattern,
678 const char *pattern_end)
9590837b
KT
679{
680 while (filename < filename_end && pattern < pattern_end) {
681 char c;
682 if (*pattern != '\\') {
683 if (*filename++ != *pattern++)
684 return false;
685 continue;
686 }
687 c = *filename;
688 pattern++;
689 switch (*pattern) {
690 int i;
691 int j;
692 case '?':
693 if (c == '/') {
694 return false;
695 } else if (c == '\\') {
696 if (filename[1] == '\\')
697 filename++;
698 else if (tomoyo_is_byte_range(filename + 1))
699 filename += 3;
700 else
701 return false;
702 }
703 break;
704 case '\\':
705 if (c != '\\')
706 return false;
707 if (*++filename != '\\')
708 return false;
709 break;
710 case '+':
711 if (!isdigit(c))
712 return false;
713 break;
714 case 'x':
715 if (!isxdigit(c))
716 return false;
717 break;
718 case 'a':
719 if (!tomoyo_is_alphabet_char(c))
720 return false;
721 break;
722 case '0':
723 case '1':
724 case '2':
725 case '3':
726 if (c == '\\' && tomoyo_is_byte_range(filename + 1)
727 && strncmp(filename + 1, pattern, 3) == 0) {
728 filename += 3;
729 pattern += 2;
730 break;
731 }
732 return false; /* Not matched. */
733 case '*':
734 case '@':
735 for (i = 0; i <= filename_end - filename; i++) {
7539cf4b 736 if (tomoyo_file_matches_pattern2(
9590837b
KT
737 filename + i, filename_end,
738 pattern + 1, pattern_end))
739 return true;
740 c = filename[i];
741 if (c == '.' && *pattern == '@')
742 break;
743 if (c != '\\')
744 continue;
745 if (filename[i + 1] == '\\')
746 i++;
747 else if (tomoyo_is_byte_range(filename + i + 1))
748 i += 3;
749 else
750 break; /* Bad pattern. */
751 }
752 return false; /* Not matched. */
753 default:
754 j = 0;
755 c = *pattern;
756 if (c == '$') {
757 while (isdigit(filename[j]))
758 j++;
759 } else if (c == 'X') {
760 while (isxdigit(filename[j]))
761 j++;
762 } else if (c == 'A') {
763 while (tomoyo_is_alphabet_char(filename[j]))
764 j++;
765 }
766 for (i = 1; i <= j; i++) {
7539cf4b 767 if (tomoyo_file_matches_pattern2(
9590837b
KT
768 filename + i, filename_end,
769 pattern + 1, pattern_end))
770 return true;
771 }
772 return false; /* Not matched or bad pattern. */
773 }
774 filename++;
775 pattern++;
776 }
777 while (*pattern == '\\' &&
778 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
779 pattern += 2;
780 return filename == filename_end && pattern == pattern_end;
781}
782
783/**
7539cf4b 784 * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
9590837b
KT
785 *
786 * @filename: The start of string to check.
787 * @filename_end: The end of string to check.
788 * @pattern: The start of pattern to compare.
789 * @pattern_end: The end of pattern to compare.
790 *
791 * Returns true if @filename matches @pattern, false otherwise.
792 */
7539cf4b 793static bool tomoyo_file_matches_pattern(const char *filename,
9590837b
KT
794 const char *filename_end,
795 const char *pattern,
796 const char *pattern_end)
797{
798 const char *pattern_start = pattern;
799 bool first = true;
800 bool result;
801
802 while (pattern < pattern_end - 1) {
803 /* Split at "\-" pattern. */
804 if (*pattern++ != '\\' || *pattern++ != '-')
805 continue;
7539cf4b
TH
806 result = tomoyo_file_matches_pattern2(filename,
807 filename_end,
808 pattern_start,
809 pattern - 2);
9590837b
KT
810 if (first)
811 result = !result;
812 if (result)
813 return false;
814 first = false;
815 pattern_start = pattern;
816 }
7539cf4b
TH
817 result = tomoyo_file_matches_pattern2(filename, filename_end,
818 pattern_start, pattern_end);
9590837b
KT
819 return first ? result : !result;
820}
821
7539cf4b
TH
822/**
823 * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
824 *
825 * @f: The start of string to check.
826 * @p: The start of pattern to compare.
827 *
828 * Returns true if @f matches @p, false otherwise.
829 */
830static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
831{
832 const char *f_delimiter;
833 const char *p_delimiter;
834
835 while (*f && *p) {
836 f_delimiter = strchr(f, '/');
837 if (!f_delimiter)
838 f_delimiter = f + strlen(f);
839 p_delimiter = strchr(p, '/');
840 if (!p_delimiter)
841 p_delimiter = p + strlen(p);
842 if (*p == '\\' && *(p + 1) == '{')
843 goto recursive;
844 if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
845 p_delimiter))
846 return false;
847 f = f_delimiter;
848 if (*f)
849 f++;
850 p = p_delimiter;
851 if (*p)
852 p++;
853 }
854 /* Ignore trailing "\*" and "\@" in @pattern. */
855 while (*p == '\\' &&
856 (*(p + 1) == '*' || *(p + 1) == '@'))
857 p += 2;
858 return !*f && !*p;
859 recursive:
860 /*
861 * The "\{" pattern is permitted only after '/' character.
862 * This guarantees that below "*(p - 1)" is safe.
863 * Also, the "\}" pattern is permitted only before '/' character
864 * so that "\{" + "\}" pair will not break the "\-" operator.
865 */
866 if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
867 *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
868 return false; /* Bad pattern. */
869 do {
870 /* Compare current component with pattern. */
871 if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
872 p_delimiter - 2))
873 break;
874 /* Proceed to next component. */
875 f = f_delimiter;
876 if (!*f)
877 break;
878 f++;
879 /* Continue comparison. */
880 if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
881 return true;
882 f_delimiter = strchr(f, '/');
883 } while (f_delimiter);
884 return false; /* Not matched. */
885}
886
9590837b
KT
887/**
888 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
7539cf4b 889 *
9590837b
KT
890 * @filename: The filename to check.
891 * @pattern: The pattern to compare.
892 *
893 * Returns true if matches, false otherwise.
894 *
895 * The following patterns are available.
896 * \\ \ itself.
897 * \ooo Octal representation of a byte.
7539cf4b
TH
898 * \* Zero or more repetitions of characters other than '/'.
899 * \@ Zero or more repetitions of characters other than '/' or '.'.
9590837b 900 * \? 1 byte character other than '/'.
7539cf4b 901 * \$ One or more repetitions of decimal digits.
9590837b 902 * \+ 1 decimal digit.
7539cf4b 903 * \X One or more repetitions of hexadecimal digits.
9590837b 904 * \x 1 hexadecimal digit.
7539cf4b 905 * \A One or more repetitions of alphabet characters.
9590837b 906 * \a 1 alphabet character.
7539cf4b 907 *
9590837b 908 * \- Subtraction operator.
7539cf4b
TH
909 *
910 * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
911 * /dir/dir/dir/ ).
9590837b
KT
912 */
913bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
914 const struct tomoyo_path_info *pattern)
915{
9590837b
KT
916 const char *f = filename->name;
917 const char *p = pattern->name;
918 const int len = pattern->const_len;
919
920 /* If @pattern doesn't contain pattern, I can use strcmp(). */
921 if (!pattern->is_patterned)
922 return !tomoyo_pathcmp(filename, pattern);
7539cf4b
TH
923 /* Don't compare directory and non-directory. */
924 if (filename->is_dir != pattern->is_dir)
9590837b
KT
925 return false;
926 /* Compare the initial length without patterns. */
927 if (strncmp(f, p, len))
928 return false;
929 f += len;
930 p += len;
7539cf4b 931 return tomoyo_path_matches_pattern2(f, p);
9590837b
KT
932}
933
934/**
935 * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure.
936 *
937 * @head: Pointer to "struct tomoyo_io_buffer".
938 * @fmt: The printf()'s format string, followed by parameters.
939 *
940 * Returns true if output was written, false otherwise.
941 *
942 * The snprintf() will truncate, but tomoyo_io_printf() won't.
943 */
944bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
945{
946 va_list args;
947 int len;
948 int pos = head->read_avail;
949 int size = head->readbuf_size - pos;
950
951 if (size <= 0)
952 return false;
953 va_start(args, fmt);
954 len = vsnprintf(head->read_buf + pos, size, fmt, args);
955 va_end(args);
956 if (pos + len >= head->readbuf_size)
957 return false;
958 head->read_avail += len;
959 return true;
960}
961
962/**
963 * tomoyo_get_exe - Get tomoyo_realpath() of current process.
964 *
965 * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
966 *
8e2d39a1 967 * This function uses kzalloc(), so the caller must call kfree()
9590837b
KT
968 * if this function didn't return NULL.
969 */
970static const char *tomoyo_get_exe(void)
971{
972 struct mm_struct *mm = current->mm;
973 struct vm_area_struct *vma;
974 const char *cp = NULL;
975
976 if (!mm)
977 return NULL;
978 down_read(&mm->mmap_sem);
979 for (vma = mm->mmap; vma; vma = vma->vm_next) {
980 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
981 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
982 break;
983 }
984 }
985 up_read(&mm->mmap_sem);
986 return cp;
987}
988
9590837b
KT
989/**
990 * tomoyo_check_flags - Check mode for specified functionality.
991 *
992 * @domain: Pointer to "struct tomoyo_domain_info".
993 * @index: The functionality to check mode.
994 *
995 * TOMOYO checks only process context.
996 * This code disables TOMOYO's enforcement in case the function is called from
997 * interrupt context.
998 */
999unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
1000 const u8 index)
1001{
1002 const u8 profile = domain->profile;
1003
1004 if (WARN_ON(in_interrupt()))
1005 return 0;
1006 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX
1007#if TOMOYO_MAX_PROFILES != 256
1008 && profile < TOMOYO_MAX_PROFILES
1009#endif
1010 && tomoyo_profile_ptr[profile] ?
1011 tomoyo_profile_ptr[profile]->value[index] : 0;
1012}
1013
1014/**
1015 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode.
1016 *
1017 * @domain: Pointer to "struct tomoyo_domain_info".
1018 *
1019 * Returns true if domain policy violation warning should be printed to
1020 * console.
1021 */
1022bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
1023{
1024 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0;
1025}
1026
1027/**
1028 * tomoyo_domain_quota_is_ok - Check for domain's quota.
1029 *
cb0abe6a 1030 * @r: Pointer to "struct tomoyo_request_info".
9590837b
KT
1031 *
1032 * Returns true if the domain is not exceeded quota, false otherwise.
fdb8ebb7
TH
1033 *
1034 * Caller holds tomoyo_read_lock().
9590837b 1035 */
17fcfbd9 1036static bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
9590837b
KT
1037{
1038 unsigned int count = 0;
cb0abe6a 1039 struct tomoyo_domain_info *domain = r->domain;
9590837b
KT
1040 struct tomoyo_acl_info *ptr;
1041
cb0abe6a
TH
1042 if (r->mode != TOMOYO_CONFIG_LEARNING)
1043 return false;
9590837b
KT
1044 if (!domain)
1045 return true;
fdb8ebb7 1046 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
ea13ddba 1047 switch (ptr->type) {
a1f9bb6a 1048 u16 perm;
937bf613 1049 u8 i;
7ef61233 1050 case TOMOYO_TYPE_PATH_ACL:
a1f9bb6a
TH
1051 perm = container_of(ptr, struct tomoyo_path_acl, head)
1052 ->perm;
7ef61233 1053 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
937bf613
TH
1054 if (perm & (1 << i))
1055 count++;
7ef61233 1056 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
937bf613 1057 count -= 2;
9590837b 1058 break;
7ef61233
TH
1059 case TOMOYO_TYPE_PATH2_ACL:
1060 perm = container_of(ptr, struct tomoyo_path2_acl, head)
1061 ->perm;
1062 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
937bf613
TH
1063 if (perm & (1 << i))
1064 count++;
9590837b 1065 break;
a1f9bb6a
TH
1066 case TOMOYO_TYPE_PATH_NUMBER_ACL:
1067 perm = container_of(ptr, struct tomoyo_path_number_acl,
1068 head)->perm;
1069 for (i = 0; i < TOMOYO_MAX_PATH_NUMBER_OPERATION; i++)
1070 if (perm & (1 << i))
1071 count++;
1072 break;
1073 case TOMOYO_TYPE_PATH_NUMBER3_ACL:
1074 perm = container_of(ptr, struct tomoyo_path_number3_acl,
1075 head)->perm;
1076 for (i = 0; i < TOMOYO_MAX_PATH_NUMBER3_OPERATION; i++)
1077 if (perm & (1 << i))
1078 count++;
1079 break;
2106ccd9
TH
1080 case TOMOYO_TYPE_MOUNT_ACL:
1081 if (!container_of(ptr, struct tomoyo_mount_acl, head)->
1082 is_deleted)
1083 count++;
9590837b
KT
1084 }
1085 }
9590837b
KT
1086 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
1087 return true;
1088 if (!domain->quota_warned) {
1089 domain->quota_warned = true;
1090 printk(KERN_WARNING "TOMOYO-WARNING: "
1091 "Domain '%s' has so many ACLs to hold. "
1092 "Stopped learning mode.\n", domain->domainname->name);
1093 }
1094 return false;
1095}
1096
1097/**
1098 * tomoyo_find_or_assign_new_profile - Create a new profile.
1099 *
1100 * @profile: Profile number to create.
1101 *
1102 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
1103 */
1104static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
1105 int profile)
1106{
9590837b
KT
1107 struct tomoyo_profile *ptr = NULL;
1108 int i;
1109
1110 if (profile >= TOMOYO_MAX_PROFILES)
1111 return NULL;
29282381
TH
1112 if (mutex_lock_interruptible(&tomoyo_policy_lock))
1113 return NULL;
9590837b
KT
1114 ptr = tomoyo_profile_ptr[profile];
1115 if (ptr)
1116 goto ok;
4e5d6f7e 1117 ptr = kmalloc(sizeof(*ptr), GFP_NOFS);
cd7bec6a
TH
1118 if (!tomoyo_memory_ok(ptr)) {
1119 kfree(ptr);
181427a7 1120 ptr = NULL;
9590837b 1121 goto ok;
cd7bec6a 1122 }
9590837b
KT
1123 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
1124 ptr->value[i] = tomoyo_control_array[i].current_value;
1125 mb(); /* Avoid out-of-order execution. */
1126 tomoyo_profile_ptr[profile] = ptr;
1127 ok:
29282381 1128 mutex_unlock(&tomoyo_policy_lock);
9590837b
KT
1129 return ptr;
1130}
1131
1132/**
1133 * tomoyo_write_profile - Write to profile table.
1134 *
1135 * @head: Pointer to "struct tomoyo_io_buffer".
1136 *
1137 * Returns 0 on success, negative value otherwise.
1138 */
1139static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
1140{
1141 char *data = head->write_buf;
1142 unsigned int i;
1143 unsigned int value;
1144 char *cp;
1145 struct tomoyo_profile *profile;
1146 unsigned long num;
1147
1148 cp = strchr(data, '-');
1149 if (cp)
1150 *cp = '\0';
1151 if (strict_strtoul(data, 10, &num))
1152 return -EINVAL;
1153 if (cp)
1154 data = cp + 1;
1155 profile = tomoyo_find_or_assign_new_profile(num);
1156 if (!profile)
1157 return -EINVAL;
1158 cp = strchr(data, '=');
1159 if (!cp)
1160 return -EINVAL;
1161 *cp = '\0';
1162 if (!strcmp(data, "COMMENT")) {
bf24fb01
TH
1163 const struct tomoyo_path_info *old_comment = profile->comment;
1164 profile->comment = tomoyo_get_name(cp + 1);
1165 tomoyo_put_name(old_comment);
9590837b
KT
1166 return 0;
1167 }
1168 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
1169 if (strcmp(data, tomoyo_control_array[i].keyword))
1170 continue;
1171 if (sscanf(cp + 1, "%u", &value) != 1) {
1172 int j;
1173 const char **modes;
1174 switch (i) {
1175 case TOMOYO_VERBOSE:
1176 modes = tomoyo_mode_2;
1177 break;
1178 default:
1179 modes = tomoyo_mode_4;
1180 break;
1181 }
1182 for (j = 0; j < 4; j++) {
1183 if (strcmp(cp + 1, modes[j]))
1184 continue;
1185 value = j;
1186 break;
1187 }
1188 if (j == 4)
1189 return -EINVAL;
1190 } else if (value > tomoyo_control_array[i].max_value) {
1191 value = tomoyo_control_array[i].max_value;
1192 }
1193 profile->value[i] = value;
1194 return 0;
1195 }
1196 return -EINVAL;
1197}
1198
1199/**
1200 * tomoyo_read_profile - Read from profile table.
1201 *
1202 * @head: Pointer to "struct tomoyo_io_buffer".
1203 *
1204 * Returns 0.
1205 */
1206static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1207{
1208 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1;
1209 int step;
1210
1211 if (head->read_eof)
1212 return 0;
1213 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total;
1214 step++) {
1215 const u8 index = step / total;
1216 u8 type = step % total;
1217 const struct tomoyo_profile *profile
1218 = tomoyo_profile_ptr[index];
1219 head->read_step = step;
1220 if (!profile)
1221 continue;
1222 if (!type) { /* Print profile' comment tag. */
1223 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n",
1224 index, profile->comment ?
1225 profile->comment->name : ""))
1226 break;
1227 continue;
1228 }
1229 type--;
1230 if (type < TOMOYO_MAX_CONTROL_INDEX) {
1231 const unsigned int value = profile->value[type];
1232 const char **modes = NULL;
1233 const char *keyword
1234 = tomoyo_control_array[type].keyword;
1235 switch (tomoyo_control_array[type].max_value) {
1236 case 3:
1237 modes = tomoyo_mode_4;
1238 break;
1239 case 1:
1240 modes = tomoyo_mode_2;
1241 break;
1242 }
1243 if (modes) {
1244 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index,
1245 keyword, modes[value]))
1246 break;
1247 } else {
1248 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index,
1249 keyword, value))
1250 break;
1251 }
1252 }
1253 }
1254 if (step == TOMOYO_MAX_PROFILES * total)
1255 head->read_eof = true;
1256 return 0;
1257}
1258
c3fa109a
TH
1259/*
1260 * tomoyo_policy_manager_list is used for holding list of domainnames or
1261 * programs which are permitted to modify configuration via
1262 * /sys/kernel/security/tomoyo/ interface.
1263 *
1264 * An entry is added by
1265 *
1266 * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
1267 * /sys/kernel/security/tomoyo/manager
1268 * (if you want to specify by a domainname)
1269 *
1270 * or
1271 *
1272 * # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager
1273 * (if you want to specify by a program's location)
1274 *
1275 * and is deleted by
1276 *
1277 * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
1278 * /sys/kernel/security/tomoyo/manager
1279 *
1280 * or
1281 *
1282 * # echo 'delete /usr/lib/ccs/editpolicy' > \
1283 * /sys/kernel/security/tomoyo/manager
1284 *
1285 * and all entries are retrieved by
1286 *
1287 * # cat /sys/kernel/security/tomoyo/manager
1288 */
847b173e 1289LIST_HEAD(tomoyo_policy_manager_list);
9590837b
KT
1290
1291/**
1292 * tomoyo_update_manager_entry - Add a manager entry.
1293 *
1294 * @manager: The path to manager or the domainnamme.
1295 * @is_delete: True if it is a delete request.
1296 *
1297 * Returns 0 on success, negative value otherwise.
fdb8ebb7
TH
1298 *
1299 * Caller holds tomoyo_read_lock().
9590837b
KT
1300 */
1301static int tomoyo_update_manager_entry(const char *manager,
1302 const bool is_delete)
1303{
9590837b 1304 struct tomoyo_policy_manager_entry *ptr;
9e4b50e9 1305 struct tomoyo_policy_manager_entry e = { };
ca0b7df3 1306 int error = is_delete ? -ENOENT : -ENOMEM;
9590837b
KT
1307
1308 if (tomoyo_is_domain_def(manager)) {
17080008 1309 if (!tomoyo_is_correct_domain(manager))
9590837b 1310 return -EINVAL;
9e4b50e9 1311 e.is_domain = true;
9590837b 1312 } else {
17080008 1313 if (!tomoyo_is_correct_path(manager, 1, -1, -1))
9590837b
KT
1314 return -EINVAL;
1315 }
9e4b50e9
TH
1316 e.manager = tomoyo_get_name(manager);
1317 if (!e.manager)
9590837b 1318 return -ENOMEM;
29282381
TH
1319 if (mutex_lock_interruptible(&tomoyo_policy_lock))
1320 goto out;
fdb8ebb7 1321 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
9e4b50e9 1322 if (ptr->manager != e.manager)
9590837b
KT
1323 continue;
1324 ptr->is_deleted = is_delete;
1325 error = 0;
ca0b7df3 1326 break;
9590837b 1327 }
9e4b50e9
TH
1328 if (!is_delete && error) {
1329 struct tomoyo_policy_manager_entry *entry =
1330 tomoyo_commit_ok(&e, sizeof(e));
1331 if (entry) {
1332 list_add_tail_rcu(&entry->list,
1333 &tomoyo_policy_manager_list);
1334 error = 0;
1335 }
9590837b 1336 }
f737d95d 1337 mutex_unlock(&tomoyo_policy_lock);
29282381 1338 out:
9e4b50e9 1339 tomoyo_put_name(e.manager);
9590837b
KT
1340 return error;
1341}
1342
1343/**
1344 * tomoyo_write_manager_policy - Write manager policy.
1345 *
1346 * @head: Pointer to "struct tomoyo_io_buffer".
1347 *
1348 * Returns 0 on success, negative value otherwise.
fdb8ebb7
TH
1349 *
1350 * Caller holds tomoyo_read_lock().
9590837b
KT
1351 */
1352static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1353{
1354 char *data = head->write_buf;
1355 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
1356
1357 if (!strcmp(data, "manage_by_non_root")) {
1358 tomoyo_manage_by_non_root = !is_delete;
1359 return 0;
1360 }
1361 return tomoyo_update_manager_entry(data, is_delete);
1362}
1363
1364/**
1365 * tomoyo_read_manager_policy - Read manager policy.
1366 *
1367 * @head: Pointer to "struct tomoyo_io_buffer".
1368 *
1369 * Returns 0.
fdb8ebb7
TH
1370 *
1371 * Caller holds tomoyo_read_lock().
9590837b
KT
1372 */
1373static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1374{
1375 struct list_head *pos;
1376 bool done = true;
1377
1378 if (head->read_eof)
1379 return 0;
9590837b
KT
1380 list_for_each_cookie(pos, head->read_var2,
1381 &tomoyo_policy_manager_list) {
1382 struct tomoyo_policy_manager_entry *ptr;
1383 ptr = list_entry(pos, struct tomoyo_policy_manager_entry,
1384 list);
1385 if (ptr->is_deleted)
1386 continue;
7d2948b1
TH
1387 done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
1388 if (!done)
9590837b 1389 break;
9590837b 1390 }
9590837b
KT
1391 head->read_eof = done;
1392 return 0;
1393}
1394
1395/**
1396 * tomoyo_is_policy_manager - Check whether the current process is a policy manager.
1397 *
1398 * Returns true if the current process is permitted to modify policy
1399 * via /sys/kernel/security/tomoyo/ interface.
fdb8ebb7
TH
1400 *
1401 * Caller holds tomoyo_read_lock().
9590837b
KT
1402 */
1403static bool tomoyo_is_policy_manager(void)
1404{
1405 struct tomoyo_policy_manager_entry *ptr;
1406 const char *exe;
1407 const struct task_struct *task = current;
1408 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
1409 bool found = false;
1410
1411 if (!tomoyo_policy_loaded)
1412 return true;
1413 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
1414 return false;
fdb8ebb7 1415 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
9590837b
KT
1416 if (!ptr->is_deleted && ptr->is_domain
1417 && !tomoyo_pathcmp(domainname, ptr->manager)) {
1418 found = true;
1419 break;
1420 }
1421 }
9590837b
KT
1422 if (found)
1423 return true;
1424 exe = tomoyo_get_exe();
1425 if (!exe)
1426 return false;
fdb8ebb7 1427 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
9590837b
KT
1428 if (!ptr->is_deleted && !ptr->is_domain
1429 && !strcmp(exe, ptr->manager->name)) {
1430 found = true;
1431 break;
1432 }
1433 }
9590837b
KT
1434 if (!found) { /* Reduce error messages. */
1435 static pid_t last_pid;
1436 const pid_t pid = current->pid;
1437 if (last_pid != pid) {
1438 printk(KERN_WARNING "%s ( %s ) is not permitted to "
1439 "update policies.\n", domainname->name, exe);
1440 last_pid = pid;
1441 }
1442 }
8e2d39a1 1443 kfree(exe);
9590837b
KT
1444 return found;
1445}
1446
1447/**
1448 * tomoyo_is_select_one - Parse select command.
1449 *
1450 * @head: Pointer to "struct tomoyo_io_buffer".
1451 * @data: String to parse.
1452 *
1453 * Returns true on success, false otherwise.
fdb8ebb7
TH
1454 *
1455 * Caller holds tomoyo_read_lock().
9590837b
KT
1456 */
1457static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1458 const char *data)
1459{
1460 unsigned int pid;
1461 struct tomoyo_domain_info *domain = NULL;
1462
1463 if (sscanf(data, "pid=%u", &pid) == 1) {
1464 struct task_struct *p;
1fcdc7c5 1465 rcu_read_lock();
9590837b
KT
1466 read_lock(&tasklist_lock);
1467 p = find_task_by_vpid(pid);
1468 if (p)
1469 domain = tomoyo_real_domain(p);
1470 read_unlock(&tasklist_lock);
1fcdc7c5 1471 rcu_read_unlock();
9590837b 1472 } else if (!strncmp(data, "domain=", 7)) {
fdb8ebb7 1473 if (tomoyo_is_domain_def(data + 7))
9590837b 1474 domain = tomoyo_find_domain(data + 7);
9590837b
KT
1475 } else
1476 return false;
1477 head->write_var1 = domain;
1478 /* Accessing read_buf is safe because head->io_sem is held. */
1479 if (!head->read_buf)
1480 return true; /* Do nothing if open(O_WRONLY). */
1481 head->read_avail = 0;
1482 tomoyo_io_printf(head, "# select %s\n", data);
1483 head->read_single_domain = true;
1484 head->read_eof = !domain;
1485 if (domain) {
1486 struct tomoyo_domain_info *d;
1487 head->read_var1 = NULL;
fdb8ebb7 1488 list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
9590837b
KT
1489 if (d == domain)
1490 break;
1491 head->read_var1 = &d->list;
1492 }
9590837b
KT
1493 head->read_var2 = NULL;
1494 head->read_bit = 0;
1495 head->read_step = 0;
1496 if (domain->is_deleted)
1497 tomoyo_io_printf(head, "# This is a deleted domain.\n");
1498 }
1499 return true;
1500}
1501
ccf135f5
TH
1502/**
1503 * tomoyo_delete_domain - Delete a domain.
1504 *
1505 * @domainname: The name of domain.
1506 *
1507 * Returns 0.
fdb8ebb7
TH
1508 *
1509 * Caller holds tomoyo_read_lock().
ccf135f5
TH
1510 */
1511static int tomoyo_delete_domain(char *domainname)
1512{
1513 struct tomoyo_domain_info *domain;
1514 struct tomoyo_path_info name;
1515
1516 name.name = domainname;
1517 tomoyo_fill_path_info(&name);
29282381
TH
1518 if (mutex_lock_interruptible(&tomoyo_policy_lock))
1519 return 0;
ccf135f5 1520 /* Is there an active domain? */
fdb8ebb7 1521 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
ccf135f5
TH
1522 /* Never delete tomoyo_kernel_domain */
1523 if (domain == &tomoyo_kernel_domain)
1524 continue;
1525 if (domain->is_deleted ||
1526 tomoyo_pathcmp(domain->domainname, &name))
1527 continue;
1528 domain->is_deleted = true;
1529 break;
1530 }
f737d95d 1531 mutex_unlock(&tomoyo_policy_lock);
ccf135f5
TH
1532 return 0;
1533}
1534
17fcfbd9
TH
1535/**
1536 * tomoyo_write_domain_policy2 - Write domain policy.
1537 *
1538 * @head: Pointer to "struct tomoyo_io_buffer".
1539 *
1540 * Returns 0 on success, negative value otherwise.
1541 *
1542 * Caller holds tomoyo_read_lock().
1543 */
1544static int tomoyo_write_domain_policy2(char *data,
1545 struct tomoyo_domain_info *domain,
1546 const bool is_delete)
1547{
1548 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT))
1549 return tomoyo_write_mount_policy(data, domain, is_delete);
1550 return tomoyo_write_file_policy(data, domain, is_delete);
1551}
1552
9590837b
KT
1553/**
1554 * tomoyo_write_domain_policy - Write domain policy.
1555 *
1556 * @head: Pointer to "struct tomoyo_io_buffer".
1557 *
1558 * Returns 0 on success, negative value otherwise.
fdb8ebb7
TH
1559 *
1560 * Caller holds tomoyo_read_lock().
9590837b
KT
1561 */
1562static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1563{
1564 char *data = head->write_buf;
1565 struct tomoyo_domain_info *domain = head->write_var1;
1566 bool is_delete = false;
1567 bool is_select = false;
9590837b
KT
1568 unsigned int profile;
1569
1570 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
1571 is_delete = true;
1572 else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
1573 is_select = true;
9590837b
KT
1574 if (is_select && tomoyo_is_select_one(head, data))
1575 return 0;
1576 /* Don't allow updating policies by non manager programs. */
1577 if (!tomoyo_is_policy_manager())
1578 return -EPERM;
1579 if (tomoyo_is_domain_def(data)) {
1580 domain = NULL;
1581 if (is_delete)
1582 tomoyo_delete_domain(data);
fdb8ebb7 1583 else if (is_select)
9590837b 1584 domain = tomoyo_find_domain(data);
fdb8ebb7 1585 else
9590837b
KT
1586 domain = tomoyo_find_or_assign_new_domain(data, 0);
1587 head->write_var1 = domain;
1588 return 0;
1589 }
1590 if (!domain)
1591 return -EINVAL;
1592
1593 if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1
1594 && profile < TOMOYO_MAX_PROFILES) {
1595 if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)
1596 domain->profile = (u8) profile;
1597 return 0;
1598 }
1599 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
ea13ddba 1600 domain->ignore_global_allow_read = !is_delete;
9590837b
KT
1601 return 0;
1602 }
17fcfbd9 1603 return tomoyo_write_domain_policy2(data, domain, is_delete);
9590837b
KT
1604}
1605
1606/**
7ef61233 1607 * tomoyo_print_path_acl - Print a single path ACL entry.
9590837b
KT
1608 *
1609 * @head: Pointer to "struct tomoyo_io_buffer".
7ef61233 1610 * @ptr: Pointer to "struct tomoyo_path_acl".
9590837b
KT
1611 *
1612 * Returns true on success, false otherwise.
1613 */
7ef61233
TH
1614static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
1615 struct tomoyo_path_acl *ptr)
9590837b
KT
1616{
1617 int pos;
1618 u8 bit;
a1f9bb6a 1619 const u16 perm = ptr->perm;
9590837b 1620
7ef61233 1621 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
9590837b
KT
1622 if (!(perm & (1 << bit)))
1623 continue;
1624 /* Print "read/write" instead of "read" and "write". */
7ef61233
TH
1625 if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE)
1626 && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
9590837b 1627 continue;
9590837b 1628 pos = head->read_avail;
7762fbff
TH
1629 if (!tomoyo_io_printf(head, "allow_%s ",
1630 tomoyo_path2keyword(bit)) ||
1631 !tomoyo_print_name_union(head, &ptr->name) ||
1632 !tomoyo_io_printf(head, "\n"))
9590837b
KT
1633 goto out;
1634 }
1635 head->read_bit = 0;
1636 return true;
1637 out:
1638 head->read_bit = bit;
1639 head->read_avail = pos;
1640 return false;
1641}
1642
1643/**
7ef61233 1644 * tomoyo_print_path2_acl - Print a double path ACL entry.
9590837b
KT
1645 *
1646 * @head: Pointer to "struct tomoyo_io_buffer".
7ef61233 1647 * @ptr: Pointer to "struct tomoyo_path2_acl".
9590837b
KT
1648 *
1649 * Returns true on success, false otherwise.
1650 */
7ef61233
TH
1651static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
1652 struct tomoyo_path2_acl *ptr)
9590837b
KT
1653{
1654 int pos;
9590837b
KT
1655 const u8 perm = ptr->perm;
1656 u8 bit;
1657
7ef61233 1658 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
9590837b
KT
1659 if (!(perm & (1 << bit)))
1660 continue;
9590837b 1661 pos = head->read_avail;
7762fbff
TH
1662 if (!tomoyo_io_printf(head, "allow_%s ",
1663 tomoyo_path22keyword(bit)) ||
1664 !tomoyo_print_name_union(head, &ptr->name1) ||
1665 !tomoyo_print_name_union(head, &ptr->name2) ||
1666 !tomoyo_io_printf(head, "\n"))
9590837b
KT
1667 goto out;
1668 }
1669 head->read_bit = 0;
1670 return true;
1671 out:
1672 head->read_bit = bit;
1673 head->read_avail = pos;
1674 return false;
1675}
1676
a1f9bb6a
TH
1677/**
1678 * tomoyo_print_path_number_acl - Print a path_number ACL entry.
1679 *
1680 * @head: Pointer to "struct tomoyo_io_buffer".
1681 * @ptr: Pointer to "struct tomoyo_path_number_acl".
1682 *
1683 * Returns true on success, false otherwise.
1684 */
1685static bool tomoyo_print_path_number_acl(struct tomoyo_io_buffer *head,
1686 struct tomoyo_path_number_acl *ptr)
1687{
1688 int pos;
1689 u8 bit;
1690 const u8 perm = ptr->perm;
1691 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION;
1692 bit++) {
1693 if (!(perm & (1 << bit)))
1694 continue;
1695 pos = head->read_avail;
1696 if (!tomoyo_io_printf(head, "allow_%s",
1697 tomoyo_path_number2keyword(bit)) ||
1698 !tomoyo_print_name_union(head, &ptr->name) ||
1699 !tomoyo_print_number_union(head, &ptr->number) ||
1700 !tomoyo_io_printf(head, "\n"))
1701 goto out;
1702 }
1703 head->read_bit = 0;
1704 return true;
1705 out:
1706 head->read_bit = bit;
1707 head->read_avail = pos;
1708 return false;
1709}
1710
1711/**
1712 * tomoyo_print_path_number3_acl - Print a path_number3 ACL entry.
1713 *
1714 * @head: Pointer to "struct tomoyo_io_buffer".
1715 * @ptr: Pointer to "struct tomoyo_path_number3_acl".
1716 *
1717 * Returns true on success, false otherwise.
1718 */
1719static bool tomoyo_print_path_number3_acl(struct tomoyo_io_buffer *head,
1720 struct tomoyo_path_number3_acl *ptr)
1721{
1722 int pos;
1723 u8 bit;
1724 const u16 perm = ptr->perm;
1725 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_NUMBER3_OPERATION;
1726 bit++) {
1727 if (!(perm & (1 << bit)))
1728 continue;
1729 pos = head->read_avail;
1730 if (!tomoyo_io_printf(head, "allow_%s",
1731 tomoyo_path_number32keyword(bit)) ||
1732 !tomoyo_print_name_union(head, &ptr->name) ||
1733 !tomoyo_print_number_union(head, &ptr->mode) ||
1734 !tomoyo_print_number_union(head, &ptr->major) ||
1735 !tomoyo_print_number_union(head, &ptr->minor) ||
1736 !tomoyo_io_printf(head, "\n"))
1737 goto out;
1738 }
1739 head->read_bit = 0;
1740 return true;
1741 out:
1742 head->read_bit = bit;
1743 head->read_avail = pos;
1744 return false;
1745}
1746
2106ccd9
TH
1747/**
1748 * tomoyo_print_mount_acl - Print a mount ACL entry.
1749 *
1750 * @head: Pointer to "struct tomoyo_io_buffer".
1751 * @ptr: Pointer to "struct tomoyo_mount_acl".
1752 *
1753 * Returns true on success, false otherwise.
1754 */
1755static bool tomoyo_print_mount_acl(struct tomoyo_io_buffer *head,
1756 struct tomoyo_mount_acl *ptr)
1757{
1758 const int pos = head->read_avail;
1759 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) ||
1760 !tomoyo_print_name_union(head, &ptr->dev_name) ||
1761 !tomoyo_print_name_union(head, &ptr->dir_name) ||
1762 !tomoyo_print_name_union(head, &ptr->fs_type) ||
1763 !tomoyo_print_number_union(head, &ptr->flags) ||
1764 !tomoyo_io_printf(head, "\n")) {
1765 head->read_avail = pos;
1766 return false;
1767 }
1768 return true;
1769}
1770
9590837b
KT
1771/**
1772 * tomoyo_print_entry - Print an ACL entry.
1773 *
1774 * @head: Pointer to "struct tomoyo_io_buffer".
1775 * @ptr: Pointer to an ACL entry.
1776 *
1777 * Returns true on success, false otherwise.
1778 */
1779static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1780 struct tomoyo_acl_info *ptr)
1781{
ea13ddba 1782 const u8 acl_type = ptr->type;
9590837b 1783
7ef61233
TH
1784 if (acl_type == TOMOYO_TYPE_PATH_ACL) {
1785 struct tomoyo_path_acl *acl
1786 = container_of(ptr, struct tomoyo_path_acl, head);
1787 return tomoyo_print_path_acl(head, acl);
9590837b 1788 }
7ef61233
TH
1789 if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
1790 struct tomoyo_path2_acl *acl
1791 = container_of(ptr, struct tomoyo_path2_acl, head);
1792 return tomoyo_print_path2_acl(head, acl);
9590837b 1793 }
a1f9bb6a
TH
1794 if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
1795 struct tomoyo_path_number_acl *acl
1796 = container_of(ptr, struct tomoyo_path_number_acl,
1797 head);
1798 return tomoyo_print_path_number_acl(head, acl);
1799 }
1800 if (acl_type == TOMOYO_TYPE_PATH_NUMBER3_ACL) {
1801 struct tomoyo_path_number3_acl *acl
1802 = container_of(ptr, struct tomoyo_path_number3_acl,
1803 head);
1804 return tomoyo_print_path_number3_acl(head, acl);
1805 }
2106ccd9
TH
1806 if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
1807 struct tomoyo_mount_acl *acl
1808 = container_of(ptr, struct tomoyo_mount_acl, head);
1809 return tomoyo_print_mount_acl(head, acl);
1810 }
9590837b
KT
1811 BUG(); /* This must not happen. */
1812 return false;
1813}
1814
1815/**
1816 * tomoyo_read_domain_policy - Read domain policy.
1817 *
1818 * @head: Pointer to "struct tomoyo_io_buffer".
1819 *
1820 * Returns 0.
fdb8ebb7
TH
1821 *
1822 * Caller holds tomoyo_read_lock().
9590837b
KT
1823 */
1824static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1825{
1826 struct list_head *dpos;
1827 struct list_head *apos;
1828 bool done = true;
1829
1830 if (head->read_eof)
1831 return 0;
1832 if (head->read_step == 0)
1833 head->read_step = 1;
9590837b
KT
1834 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
1835 struct tomoyo_domain_info *domain;
1836 const char *quota_exceeded = "";
1837 const char *transition_failed = "";
1838 const char *ignore_global_allow_read = "";
1839 domain = list_entry(dpos, struct tomoyo_domain_info, list);
1840 if (head->read_step != 1)
1841 goto acl_loop;
1842 if (domain->is_deleted && !head->read_single_domain)
1843 continue;
1844 /* Print domainname and flags. */
1845 if (domain->quota_warned)
1846 quota_exceeded = "quota_exceeded\n";
ea13ddba 1847 if (domain->transition_failed)
9590837b 1848 transition_failed = "transition_failed\n";
ea13ddba 1849 if (domain->ignore_global_allow_read)
9590837b
KT
1850 ignore_global_allow_read
1851 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
7d2948b1
TH
1852 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
1853 "%u\n%s%s%s\n",
1854 domain->domainname->name,
1855 domain->profile, quota_exceeded,
1856 transition_failed,
1857 ignore_global_allow_read);
1858 if (!done)
9590837b 1859 break;
9590837b
KT
1860 head->read_step = 2;
1861acl_loop:
1862 if (head->read_step == 3)
1863 goto tail_mark;
1864 /* Print ACL entries in the domain. */
9590837b 1865 list_for_each_cookie(apos, head->read_var2,
7d2948b1 1866 &domain->acl_info_list) {
9590837b
KT
1867 struct tomoyo_acl_info *ptr
1868 = list_entry(apos, struct tomoyo_acl_info,
7d2948b1
TH
1869 list);
1870 done = tomoyo_print_entry(head, ptr);
1871 if (!done)
9590837b 1872 break;
9590837b 1873 }
9590837b
KT
1874 if (!done)
1875 break;
1876 head->read_step = 3;
1877tail_mark:
7d2948b1
TH
1878 done = tomoyo_io_printf(head, "\n");
1879 if (!done)
9590837b 1880 break;
9590837b
KT
1881 head->read_step = 1;
1882 if (head->read_single_domain)
1883 break;
1884 }
9590837b
KT
1885 head->read_eof = done;
1886 return 0;
1887}
1888
1889/**
1890 * tomoyo_write_domain_profile - Assign profile for specified domain.
1891 *
1892 * @head: Pointer to "struct tomoyo_io_buffer".
1893 *
1894 * Returns 0 on success, -EINVAL otherwise.
1895 *
1896 * This is equivalent to doing
1897 *
1898 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1899 * /usr/lib/ccs/loadpolicy -d
fdb8ebb7
TH
1900 *
1901 * Caller holds tomoyo_read_lock().
9590837b
KT
1902 */
1903static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1904{
1905 char *data = head->write_buf;
1906 char *cp = strchr(data, ' ');
1907 struct tomoyo_domain_info *domain;
1908 unsigned long profile;
1909
1910 if (!cp)
1911 return -EINVAL;
1912 *cp = '\0';
9590837b 1913 domain = tomoyo_find_domain(cp + 1);
9590837b
KT
1914 if (strict_strtoul(data, 10, &profile))
1915 return -EINVAL;
1916 if (domain && profile < TOMOYO_MAX_PROFILES
1917 && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
1918 domain->profile = (u8) profile;
1919 return 0;
1920}
1921
1922/**
1923 * tomoyo_read_domain_profile - Read only domainname and profile.
1924 *
1925 * @head: Pointer to "struct tomoyo_io_buffer".
1926 *
1927 * Returns list of profile number and domainname pairs.
1928 *
1929 * This is equivalent to doing
1930 *
1931 * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy |
1932 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1933 * domainname = $0; } else if ( $1 == "use_profile" ) {
1934 * print $2 " " domainname; domainname = ""; } } ; '
fdb8ebb7
TH
1935 *
1936 * Caller holds tomoyo_read_lock().
9590837b
KT
1937 */
1938static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1939{
1940 struct list_head *pos;
1941 bool done = true;
1942
1943 if (head->read_eof)
1944 return 0;
9590837b
KT
1945 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
1946 struct tomoyo_domain_info *domain;
1947 domain = list_entry(pos, struct tomoyo_domain_info, list);
1948 if (domain->is_deleted)
1949 continue;
7d2948b1
TH
1950 done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
1951 domain->domainname->name);
1952 if (!done)
9590837b 1953 break;
9590837b 1954 }
9590837b
KT
1955 head->read_eof = done;
1956 return 0;
1957}
1958
1959/**
1960 * tomoyo_write_pid: Specify PID to obtain domainname.
1961 *
1962 * @head: Pointer to "struct tomoyo_io_buffer".
1963 *
1964 * Returns 0.
1965 */
1966static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1967{
1968 unsigned long pid;
1969 /* No error check. */
1970 strict_strtoul(head->write_buf, 10, &pid);
1971 head->read_step = (int) pid;
1972 head->read_eof = false;
1973 return 0;
1974}
1975
1976/**
1977 * tomoyo_read_pid - Get domainname of the specified PID.
1978 *
1979 * @head: Pointer to "struct tomoyo_io_buffer".
1980 *
1981 * Returns the domainname which the specified PID is in on success,
1982 * empty string otherwise.
1983 * The PID is specified by tomoyo_write_pid() so that the user can obtain
1984 * using read()/write() interface rather than sysctl() interface.
1985 */
1986static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1987{
1988 if (head->read_avail == 0 && !head->read_eof) {
1989 const int pid = head->read_step;
1990 struct task_struct *p;
1991 struct tomoyo_domain_info *domain = NULL;
1fcdc7c5 1992 rcu_read_lock();
9590837b
KT
1993 read_lock(&tasklist_lock);
1994 p = find_task_by_vpid(pid);
1995 if (p)
1996 domain = tomoyo_real_domain(p);
1997 read_unlock(&tasklist_lock);
1fcdc7c5 1998 rcu_read_unlock();
9590837b
KT
1999 if (domain)
2000 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
2001 domain->domainname->name);
2002 head->read_eof = true;
2003 }
2004 return 0;
2005}
2006
2007/**
2008 * tomoyo_write_exception_policy - Write exception policy.
2009 *
2010 * @head: Pointer to "struct tomoyo_io_buffer".
2011 *
2012 * Returns 0 on success, negative value otherwise.
fdb8ebb7
TH
2013 *
2014 * Caller holds tomoyo_read_lock().
9590837b
KT
2015 */
2016static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
2017{
2018 char *data = head->write_buf;
2019 bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
2020
2021 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN))
2022 return tomoyo_write_domain_keeper_policy(data, false,
2023 is_delete);
2024 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN))
2025 return tomoyo_write_domain_keeper_policy(data, true, is_delete);
2026 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN))
2027 return tomoyo_write_domain_initializer_policy(data, false,
2028 is_delete);
2029 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN))
2030 return tomoyo_write_domain_initializer_policy(data, true,
2031 is_delete);
2032 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS))
2033 return tomoyo_write_alias_policy(data, is_delete);
2034 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ))
2035 return tomoyo_write_globally_readable_policy(data, is_delete);
2036 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN))
2037 return tomoyo_write_pattern_policy(data, is_delete);
2038 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE))
2039 return tomoyo_write_no_rewrite_policy(data, is_delete);
7762fbff
TH
2040 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP))
2041 return tomoyo_write_path_group_policy(data, is_delete);
4c3e9e2d
TH
2042 if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NUMBER_GROUP))
2043 return tomoyo_write_number_group_policy(data, is_delete);
9590837b
KT
2044 return -EINVAL;
2045}
2046
2047/**
2048 * tomoyo_read_exception_policy - Read exception policy.
2049 *
2050 * @head: Pointer to "struct tomoyo_io_buffer".
2051 *
2052 * Returns 0 on success, -EINVAL otherwise.
fdb8ebb7
TH
2053 *
2054 * Caller holds tomoyo_read_lock().
9590837b
KT
2055 */
2056static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
2057{
2058 if (!head->read_eof) {
2059 switch (head->read_step) {
2060 case 0:
2061 head->read_var2 = NULL;
2062 head->read_step = 1;
2063 case 1:
2064 if (!tomoyo_read_domain_keeper_policy(head))
2065 break;
2066 head->read_var2 = NULL;
2067 head->read_step = 2;
2068 case 2:
2069 if (!tomoyo_read_globally_readable_policy(head))
2070 break;
2071 head->read_var2 = NULL;
2072 head->read_step = 3;
2073 case 3:
2074 head->read_var2 = NULL;
2075 head->read_step = 4;
2076 case 4:
2077 if (!tomoyo_read_domain_initializer_policy(head))
2078 break;
2079 head->read_var2 = NULL;
2080 head->read_step = 5;
2081 case 5:
2082 if (!tomoyo_read_alias_policy(head))
2083 break;
2084 head->read_var2 = NULL;
2085 head->read_step = 6;
2086 case 6:
2087 head->read_var2 = NULL;
2088 head->read_step = 7;
2089 case 7:
2090 if (!tomoyo_read_file_pattern(head))
2091 break;
2092 head->read_var2 = NULL;
2093 head->read_step = 8;
2094 case 8:
2095 if (!tomoyo_read_no_rewrite_policy(head))
2096 break;
2097 head->read_var2 = NULL;
2098 head->read_step = 9;
2099 case 9:
7762fbff
TH
2100 if (!tomoyo_read_path_group_policy(head))
2101 break;
2102 head->read_var1 = NULL;
2103 head->read_var2 = NULL;
2104 head->read_step = 10;
2105 case 10:
4c3e9e2d
TH
2106 if (!tomoyo_read_number_group_policy(head))
2107 break;
2108 head->read_var1 = NULL;
2109 head->read_var2 = NULL;
2110 head->read_step = 11;
2111 case 11:
9590837b
KT
2112 head->read_eof = true;
2113 break;
2114 default:
2115 return -EINVAL;
2116 }
2117 }
2118 return 0;
2119}
2120
2121/* path to policy loader */
2122static const char *tomoyo_loader = "/sbin/tomoyo-init";
2123
2124/**
2125 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
2126 *
2127 * Returns true if /sbin/tomoyo-init exists, false otherwise.
2128 */
2129static bool tomoyo_policy_loader_exists(void)
2130{
2131 /*
2132 * Don't activate MAC if the policy loader doesn't exist.
2133 * If the initrd includes /sbin/init but real-root-dev has not
2134 * mounted on / yet, activating MAC will block the system since
2135 * policies are not loaded yet.
2136 * Thus, let do_execve() call this function everytime.
2137 */
e24977d4 2138 struct path path;
9590837b 2139
e24977d4 2140 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
9590837b
KT
2141 printk(KERN_INFO "Not activating Mandatory Access Control now "
2142 "since %s doesn't exist.\n", tomoyo_loader);
2143 return false;
2144 }
e24977d4 2145 path_put(&path);
9590837b
KT
2146 return true;
2147}
2148
2149/**
2150 * tomoyo_load_policy - Run external policy loader to load policy.
2151 *
2152 * @filename: The program about to start.
2153 *
2154 * This function checks whether @filename is /sbin/init , and if so
2155 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
2156 * and then continues invocation of /sbin/init.
2157 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
2158 * writes to /sys/kernel/security/tomoyo/ interfaces.
2159 *
2160 * Returns nothing.
2161 */
2162void tomoyo_load_policy(const char *filename)
2163{
2164 char *argv[2];
2165 char *envp[3];
2166
2167 if (tomoyo_policy_loaded)
2168 return;
2169 /*
2170 * Check filename is /sbin/init or /sbin/tomoyo-start.
2171 * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't
2172 * be passed.
2173 * You can create /sbin/tomoyo-start by
2174 * "ln -s /bin/true /sbin/tomoyo-start".
2175 */
2176 if (strcmp(filename, "/sbin/init") &&
2177 strcmp(filename, "/sbin/tomoyo-start"))
2178 return;
2179 if (!tomoyo_policy_loader_exists())
2180 return;
2181
2182 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
2183 tomoyo_loader);
2184 argv[0] = (char *) tomoyo_loader;
2185 argv[1] = NULL;
2186 envp[0] = "HOME=/";
2187 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
2188 envp[2] = NULL;
2189 call_usermodehelper(argv[0], argv, envp, 1);
2190
39826a1e 2191 printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n");
9590837b
KT
2192 printk(KERN_INFO "Mandatory Access Control activated.\n");
2193 tomoyo_policy_loaded = true;
2194 { /* Check all profiles currently assigned to domains are defined. */
2195 struct tomoyo_domain_info *domain;
fdb8ebb7 2196 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
9590837b
KT
2197 const u8 profile = domain->profile;
2198 if (tomoyo_profile_ptr[profile])
2199 continue;
2200 panic("Profile %u (used by '%s') not defined.\n",
2201 profile, domain->domainname->name);
2202 }
9590837b
KT
2203 }
2204}
2205
17fcfbd9
TH
2206/**
2207 * tomoyo_print_header - Get header line of audit log.
2208 *
2209 * @r: Pointer to "struct tomoyo_request_info".
2210 *
2211 * Returns string representation.
2212 *
2213 * This function uses kmalloc(), so caller must kfree() if this function
2214 * didn't return NULL.
2215 */
2216static char *tomoyo_print_header(struct tomoyo_request_info *r)
2217{
2218 static const char *tomoyo_mode_4[4] = {
2219 "disabled", "learning", "permissive", "enforcing"
2220 };
2221 struct timeval tv;
2222 const pid_t gpid = task_pid_nr(current);
2223 static const int tomoyo_buffer_len = 4096;
2224 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
2225 if (!buffer)
2226 return NULL;
2227 do_gettimeofday(&tv);
2228 snprintf(buffer, tomoyo_buffer_len - 1,
2229 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
2230 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
2231 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
2232 tv.tv_sec, r->profile, tomoyo_mode_4[r->mode], gpid,
2233 (pid_t) sys_getpid(), (pid_t) sys_getppid(),
2234 current_uid(), current_gid(), current_euid(),
2235 current_egid(), current_suid(), current_sgid(),
2236 current_fsuid(), current_fsgid());
2237 return buffer;
2238}
2239
2240/**
2241 * tomoyo_init_audit_log - Allocate buffer for audit logs.
2242 *
2243 * @len: Required size.
2244 * @r: Pointer to "struct tomoyo_request_info".
2245 *
2246 * Returns pointer to allocated memory.
2247 *
2248 * The @len is updated to add the header lines' size on success.
2249 *
2250 * This function uses kzalloc(), so caller must kfree() if this function
2251 * didn't return NULL.
2252 */
2253static char *tomoyo_init_audit_log(int *len, struct tomoyo_request_info *r)
2254{
2255 char *buf = NULL;
2256 const char *header;
2257 const char *domainname;
2258 if (!r->domain)
2259 r->domain = tomoyo_domain();
2260 domainname = r->domain->domainname->name;
2261 header = tomoyo_print_header(r);
2262 if (!header)
2263 return NULL;
2264 *len += strlen(domainname) + strlen(header) + 10;
2265 buf = kzalloc(*len, GFP_NOFS);
2266 if (buf)
2267 snprintf(buf, (*len) - 1, "%s\n%s\n", header, domainname);
2268 kfree(header);
2269 return buf;
2270}
2271
2272/* Wait queue for tomoyo_query_list. */
2273static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
2274
2275/* Lock for manipulating tomoyo_query_list. */
2276static DEFINE_SPINLOCK(tomoyo_query_list_lock);
2277
2278/* Structure for query. */
2279struct tomoyo_query_entry {
2280 struct list_head list;
2281 char *query;
2282 int query_len;
2283 unsigned int serial;
2284 int timer;
2285 int answer;
2286};
2287
2288/* The list for "struct tomoyo_query_entry". */
2289static LIST_HEAD(tomoyo_query_list);
2290
2291/*
2292 * Number of "struct file" referring /sys/kernel/security/tomoyo/query
2293 * interface.
2294 */
2295static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
2296
2297/**
2298 * tomoyo_supervisor - Ask for the supervisor's decision.
2299 *
2300 * @r: Pointer to "struct tomoyo_request_info".
2301 * @fmt: The printf()'s format string, followed by parameters.
2302 *
2303 * Returns 0 if the supervisor decided to permit the access request which
2304 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
2305 * supervisor decided to retry the access request which violated the policy in
2306 * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2307 */
2308int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
2309{
2310 va_list args;
2311 int error = -EPERM;
2312 int pos;
2313 int len;
2314 static unsigned int tomoyo_serial;
2315 struct tomoyo_query_entry *tomoyo_query_entry = NULL;
2316 bool quota_exceeded = false;
2317 char *header;
2318 switch (r->mode) {
2319 char *buffer;
2320 case TOMOYO_CONFIG_LEARNING:
2321 if (!tomoyo_domain_quota_is_ok(r))
2322 return 0;
2323 va_start(args, fmt);
2324 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 4;
2325 va_end(args);
2326 buffer = kmalloc(len, GFP_NOFS);
2327 if (!buffer)
2328 return 0;
2329 va_start(args, fmt);
2330 vsnprintf(buffer, len - 1, fmt, args);
2331 va_end(args);
2332 tomoyo_normalize_line(buffer);
2333 tomoyo_write_domain_policy2(buffer, r->domain, false);
2334 kfree(buffer);
2335 /* fall through */
2336 case TOMOYO_CONFIG_PERMISSIVE:
2337 return 0;
2338 }
2339 if (!r->domain)
2340 r->domain = tomoyo_domain();
2341 if (!atomic_read(&tomoyo_query_observers))
2342 return -EPERM;
2343 va_start(args, fmt);
2344 len = vsnprintf((char *) &pos, sizeof(pos) - 1, fmt, args) + 32;
2345 va_end(args);
2346 header = tomoyo_init_audit_log(&len, r);
2347 if (!header)
2348 goto out;
2349 tomoyo_query_entry = kzalloc(sizeof(*tomoyo_query_entry), GFP_NOFS);
2350 if (!tomoyo_query_entry)
2351 goto out;
2352 tomoyo_query_entry->query = kzalloc(len, GFP_NOFS);
2353 if (!tomoyo_query_entry->query)
2354 goto out;
2355 len = ksize(tomoyo_query_entry->query);
2356 INIT_LIST_HEAD(&tomoyo_query_entry->list);
2357 spin_lock(&tomoyo_query_list_lock);
2358 if (tomoyo_quota_for_query && tomoyo_query_memory_size + len +
2359 sizeof(*tomoyo_query_entry) >= tomoyo_quota_for_query) {
2360 quota_exceeded = true;
2361 } else {
2362 tomoyo_query_memory_size += len + sizeof(*tomoyo_query_entry);
2363 tomoyo_query_entry->serial = tomoyo_serial++;
2364 }
2365 spin_unlock(&tomoyo_query_list_lock);
2366 if (quota_exceeded)
2367 goto out;
2368 pos = snprintf(tomoyo_query_entry->query, len - 1, "Q%u-%hu\n%s",
2369 tomoyo_query_entry->serial, r->retry, header);
2370 kfree(header);
2371 header = NULL;
2372 va_start(args, fmt);
2373 vsnprintf(tomoyo_query_entry->query + pos, len - 1 - pos, fmt, args);
2374 tomoyo_query_entry->query_len = strlen(tomoyo_query_entry->query) + 1;
2375 va_end(args);
2376 spin_lock(&tomoyo_query_list_lock);
2377 list_add_tail(&tomoyo_query_entry->list, &tomoyo_query_list);
2378 spin_unlock(&tomoyo_query_list_lock);
2379 /* Give 10 seconds for supervisor's opinion. */
2380 for (tomoyo_query_entry->timer = 0;
2381 atomic_read(&tomoyo_query_observers) && tomoyo_query_entry->timer < 100;
2382 tomoyo_query_entry->timer++) {
2383 wake_up(&tomoyo_query_wait);
2384 set_current_state(TASK_INTERRUPTIBLE);
2385 schedule_timeout(HZ / 10);
2386 if (tomoyo_query_entry->answer)
2387 break;
2388 }
2389 spin_lock(&tomoyo_query_list_lock);
2390 list_del(&tomoyo_query_entry->list);
2391 tomoyo_query_memory_size -= len + sizeof(*tomoyo_query_entry);
2392 spin_unlock(&tomoyo_query_list_lock);
2393 switch (tomoyo_query_entry->answer) {
2394 case 3: /* Asked to retry by administrator. */
2395 error = TOMOYO_RETRY_REQUEST;
2396 r->retry++;
2397 break;
2398 case 1:
2399 /* Granted by administrator. */
2400 error = 0;
2401 break;
2402 case 0:
2403 /* Timed out. */
2404 break;
2405 default:
2406 /* Rejected by administrator. */
2407 break;
2408 }
2409 out:
2410 if (tomoyo_query_entry)
2411 kfree(tomoyo_query_entry->query);
2412 kfree(tomoyo_query_entry);
2413 kfree(header);
2414 return error;
2415}
2416
2417/**
2418 * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
2419 *
2420 * @file: Pointer to "struct file".
2421 * @wait: Pointer to "poll_table".
2422 *
2423 * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
2424 *
2425 * Waits for access requests which violated policy in enforcing mode.
2426 */
2427static int tomoyo_poll_query(struct file *file, poll_table *wait)
2428{
2429 struct list_head *tmp;
2430 bool found = false;
2431 u8 i;
2432 for (i = 0; i < 2; i++) {
2433 spin_lock(&tomoyo_query_list_lock);
2434 list_for_each(tmp, &tomoyo_query_list) {
2435 struct tomoyo_query_entry *ptr
2436 = list_entry(tmp, struct tomoyo_query_entry,
2437 list);
2438 if (ptr->answer)
2439 continue;
2440 found = true;
2441 break;
2442 }
2443 spin_unlock(&tomoyo_query_list_lock);
2444 if (found)
2445 return POLLIN | POLLRDNORM;
2446 if (i)
2447 break;
2448 poll_wait(file, &tomoyo_query_wait, wait);
2449 }
2450 return 0;
2451}
2452
2453/**
2454 * tomoyo_read_query - Read access requests which violated policy in enforcing mode.
2455 *
2456 * @head: Pointer to "struct tomoyo_io_buffer".
2457 *
2458 * Returns 0.
2459 */
2460static int tomoyo_read_query(struct tomoyo_io_buffer *head)
2461{
2462 struct list_head *tmp;
2463 int pos = 0;
2464 int len = 0;
2465 char *buf;
2466 if (head->read_avail)
2467 return 0;
2468 if (head->read_buf) {
2469 kfree(head->read_buf);
2470 head->read_buf = NULL;
2471 head->readbuf_size = 0;
2472 }
2473 spin_lock(&tomoyo_query_list_lock);
2474 list_for_each(tmp, &tomoyo_query_list) {
2475 struct tomoyo_query_entry *ptr
2476 = list_entry(tmp, struct tomoyo_query_entry, list);
2477 if (ptr->answer)
2478 continue;
2479 if (pos++ != head->read_step)
2480 continue;
2481 len = ptr->query_len;
2482 break;
2483 }
2484 spin_unlock(&tomoyo_query_list_lock);
2485 if (!len) {
2486 head->read_step = 0;
2487 return 0;
2488 }
2489 buf = kzalloc(len, GFP_NOFS);
2490 if (!buf)
2491 return 0;
2492 pos = 0;
2493 spin_lock(&tomoyo_query_list_lock);
2494 list_for_each(tmp, &tomoyo_query_list) {
2495 struct tomoyo_query_entry *ptr
2496 = list_entry(tmp, struct tomoyo_query_entry, list);
2497 if (ptr->answer)
2498 continue;
2499 if (pos++ != head->read_step)
2500 continue;
2501 /*
2502 * Some query can be skipped because tomoyo_query_list
2503 * can change, but I don't care.
2504 */
2505 if (len == ptr->query_len)
2506 memmove(buf, ptr->query, len);
2507 break;
2508 }
2509 spin_unlock(&tomoyo_query_list_lock);
2510 if (buf[0]) {
2511 head->read_avail = len;
2512 head->readbuf_size = head->read_avail;
2513 head->read_buf = buf;
2514 head->read_step++;
2515 } else {
2516 kfree(buf);
2517 }
2518 return 0;
2519}
2520
2521/**
2522 * tomoyo_write_answer - Write the supervisor's decision.
2523 *
2524 * @head: Pointer to "struct tomoyo_io_buffer".
2525 *
2526 * Returns 0 on success, -EINVAL otherwise.
2527 */
2528static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2529{
2530 char *data = head->write_buf;
2531 struct list_head *tmp;
2532 unsigned int serial;
2533 unsigned int answer;
2534 spin_lock(&tomoyo_query_list_lock);
2535 list_for_each(tmp, &tomoyo_query_list) {
2536 struct tomoyo_query_entry *ptr
2537 = list_entry(tmp, struct tomoyo_query_entry, list);
2538 ptr->timer = 0;
2539 }
2540 spin_unlock(&tomoyo_query_list_lock);
2541 if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2542 return -EINVAL;
2543 spin_lock(&tomoyo_query_list_lock);
2544 list_for_each(tmp, &tomoyo_query_list) {
2545 struct tomoyo_query_entry *ptr
2546 = list_entry(tmp, struct tomoyo_query_entry, list);
2547 if (ptr->serial != serial)
2548 continue;
2549 if (!ptr->answer)
2550 ptr->answer = answer;
2551 break;
2552 }
2553 spin_unlock(&tomoyo_query_list_lock);
2554 return 0;
2555}
2556
9590837b
KT
2557/**
2558 * tomoyo_read_version: Get version.
2559 *
2560 * @head: Pointer to "struct tomoyo_io_buffer".
2561 *
2562 * Returns version information.
2563 */
2564static int tomoyo_read_version(struct tomoyo_io_buffer *head)
2565{
2566 if (!head->read_eof) {
39826a1e 2567 tomoyo_io_printf(head, "2.2.0");
9590837b
KT
2568 head->read_eof = true;
2569 }
2570 return 0;
2571}
2572
2573/**
2574 * tomoyo_read_self_domain - Get the current process's domainname.
2575 *
2576 * @head: Pointer to "struct tomoyo_io_buffer".
2577 *
2578 * Returns the current process's domainname.
2579 */
2580static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
2581{
2582 if (!head->read_eof) {
2583 /*
2584 * tomoyo_domain()->domainname != NULL
2585 * because every process belongs to a domain and
2586 * the domain's name cannot be NULL.
2587 */
2588 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
2589 head->read_eof = true;
2590 }
2591 return 0;
2592}
2593
2594/**
2595 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
2596 *
2597 * @type: Type of interface.
2598 * @file: Pointer to "struct file".
2599 *
2600 * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
fdb8ebb7
TH
2601 *
2602 * Caller acquires tomoyo_read_lock().
9590837b
KT
2603 */
2604static int tomoyo_open_control(const u8 type, struct file *file)
2605{
4e5d6f7e 2606 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
9590837b
KT
2607
2608 if (!head)
2609 return -ENOMEM;
2610 mutex_init(&head->io_sem);
17fcfbd9 2611 head->type = type;
9590837b
KT
2612 switch (type) {
2613 case TOMOYO_DOMAINPOLICY:
2614 /* /sys/kernel/security/tomoyo/domain_policy */
2615 head->write = tomoyo_write_domain_policy;
2616 head->read = tomoyo_read_domain_policy;
2617 break;
2618 case TOMOYO_EXCEPTIONPOLICY:
2619 /* /sys/kernel/security/tomoyo/exception_policy */
2620 head->write = tomoyo_write_exception_policy;
2621 head->read = tomoyo_read_exception_policy;
2622 break;
2623 case TOMOYO_SELFDOMAIN:
2624 /* /sys/kernel/security/tomoyo/self_domain */
2625 head->read = tomoyo_read_self_domain;
2626 break;
2627 case TOMOYO_DOMAIN_STATUS:
2628 /* /sys/kernel/security/tomoyo/.domain_status */
2629 head->write = tomoyo_write_domain_profile;
2630 head->read = tomoyo_read_domain_profile;
2631 break;
2632 case TOMOYO_PROCESS_STATUS:
2633 /* /sys/kernel/security/tomoyo/.process_status */
2634 head->write = tomoyo_write_pid;
2635 head->read = tomoyo_read_pid;
2636 break;
2637 case TOMOYO_VERSION:
2638 /* /sys/kernel/security/tomoyo/version */
2639 head->read = tomoyo_read_version;
2640 head->readbuf_size = 128;
2641 break;
2642 case TOMOYO_MEMINFO:
2643 /* /sys/kernel/security/tomoyo/meminfo */
2644 head->write = tomoyo_write_memory_quota;
2645 head->read = tomoyo_read_memory_counter;
2646 head->readbuf_size = 512;
2647 break;
2648 case TOMOYO_PROFILE:
2649 /* /sys/kernel/security/tomoyo/profile */
2650 head->write = tomoyo_write_profile;
2651 head->read = tomoyo_read_profile;
2652 break;
17fcfbd9
TH
2653 case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
2654 head->poll = tomoyo_poll_query;
2655 head->write = tomoyo_write_answer;
2656 head->read = tomoyo_read_query;
2657 break;
9590837b
KT
2658 case TOMOYO_MANAGER:
2659 /* /sys/kernel/security/tomoyo/manager */
2660 head->write = tomoyo_write_manager_policy;
2661 head->read = tomoyo_read_manager_policy;
2662 break;
2663 }
2664 if (!(file->f_mode & FMODE_READ)) {
2665 /*
2666 * No need to allocate read_buf since it is not opened
2667 * for reading.
2668 */
2669 head->read = NULL;
17fcfbd9
TH
2670 head->poll = NULL;
2671 } else if (!head->poll) {
2672 /* Don't allocate read_buf for poll() access. */
9590837b
KT
2673 if (!head->readbuf_size)
2674 head->readbuf_size = 4096 * 2;
4e5d6f7e 2675 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
9590837b 2676 if (!head->read_buf) {
8e2d39a1 2677 kfree(head);
9590837b
KT
2678 return -ENOMEM;
2679 }
2680 }
2681 if (!(file->f_mode & FMODE_WRITE)) {
2682 /*
2683 * No need to allocate write_buf since it is not opened
2684 * for writing.
2685 */
2686 head->write = NULL;
2687 } else if (head->write) {
2688 head->writebuf_size = 4096 * 2;
4e5d6f7e 2689 head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
9590837b 2690 if (!head->write_buf) {
8e2d39a1
TH
2691 kfree(head->read_buf);
2692 kfree(head);
9590837b
KT
2693 return -ENOMEM;
2694 }
2695 }
17fcfbd9
TH
2696 if (type != TOMOYO_QUERY)
2697 head->reader_idx = tomoyo_read_lock();
9590837b
KT
2698 file->private_data = head;
2699 /*
2700 * Call the handler now if the file is
2701 * /sys/kernel/security/tomoyo/self_domain
2702 * so that the user can use
2703 * cat < /sys/kernel/security/tomoyo/self_domain"
2704 * to know the current process's domainname.
2705 */
2706 if (type == TOMOYO_SELFDOMAIN)
2707 tomoyo_read_control(file, NULL, 0);
17fcfbd9
TH
2708 /*
2709 * If the file is /sys/kernel/security/tomoyo/query , increment the
2710 * observer counter.
2711 * The obserber counter is used by tomoyo_supervisor() to see if
2712 * there is some process monitoring /sys/kernel/security/tomoyo/query.
2713 */
2714 else if (type == TOMOYO_QUERY)
2715 atomic_inc(&tomoyo_query_observers);
9590837b
KT
2716 return 0;
2717}
2718
17fcfbd9
TH
2719/**
2720 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2721 *
2722 * @file: Pointer to "struct file".
2723 * @wait: Pointer to "poll_table".
2724 *
2725 * Waits for read readiness.
2726 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd .
2727 */
2728int tomoyo_poll_control(struct file *file, poll_table *wait)
2729{
2730 struct tomoyo_io_buffer *head = file->private_data;
2731 if (!head->poll)
2732 return -ENOSYS;
2733 return head->poll(file, wait);
2734}
2735
9590837b
KT
2736/**
2737 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
2738 *
2739 * @file: Pointer to "struct file".
2740 * @buffer: Poiner to buffer to write to.
2741 * @buffer_len: Size of @buffer.
2742 *
2743 * Returns bytes read on success, negative value otherwise.
fdb8ebb7
TH
2744 *
2745 * Caller holds tomoyo_read_lock().
9590837b
KT
2746 */
2747static int tomoyo_read_control(struct file *file, char __user *buffer,
2748 const int buffer_len)
2749{
2750 int len = 0;
2751 struct tomoyo_io_buffer *head = file->private_data;
2752 char *cp;
2753
2754 if (!head->read)
2755 return -ENOSYS;
2756 if (mutex_lock_interruptible(&head->io_sem))
2757 return -EINTR;
2758 /* Call the policy handler. */
2759 len = head->read(head);
2760 if (len < 0)
2761 goto out;
2762 /* Write to buffer. */
2763 len = head->read_avail;
2764 if (len > buffer_len)
2765 len = buffer_len;
2766 if (!len)
2767 goto out;
2768 /* head->read_buf changes by some functions. */
2769 cp = head->read_buf;
2770 if (copy_to_user(buffer, cp, len)) {
2771 len = -EFAULT;
2772 goto out;
2773 }
2774 head->read_avail -= len;
2775 memmove(cp, cp + len, head->read_avail);
2776 out:
2777 mutex_unlock(&head->io_sem);
2778 return len;
2779}
2780
2781/**
2782 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
2783 *
2784 * @file: Pointer to "struct file".
2785 * @buffer: Pointer to buffer to read from.
2786 * @buffer_len: Size of @buffer.
2787 *
2788 * Returns @buffer_len on success, negative value otherwise.
fdb8ebb7
TH
2789 *
2790 * Caller holds tomoyo_read_lock().
9590837b
KT
2791 */
2792static int tomoyo_write_control(struct file *file, const char __user *buffer,
2793 const int buffer_len)
2794{
2795 struct tomoyo_io_buffer *head = file->private_data;
2796 int error = buffer_len;
2797 int avail_len = buffer_len;
2798 char *cp0 = head->write_buf;
2799
2800 if (!head->write)
2801 return -ENOSYS;
2802 if (!access_ok(VERIFY_READ, buffer, buffer_len))
2803 return -EFAULT;
2804 /* Don't allow updating policies by non manager programs. */
2805 if (head->write != tomoyo_write_pid &&
2806 head->write != tomoyo_write_domain_policy &&
2807 !tomoyo_is_policy_manager())
2808 return -EPERM;
2809 if (mutex_lock_interruptible(&head->io_sem))
2810 return -EINTR;
2811 /* Read a line and dispatch it to the policy handler. */
2812 while (avail_len > 0) {
2813 char c;
2814 if (head->write_avail >= head->writebuf_size - 1) {
2815 error = -ENOMEM;
2816 break;
2817 } else if (get_user(c, buffer)) {
2818 error = -EFAULT;
2819 break;
2820 }
2821 buffer++;
2822 avail_len--;
2823 cp0[head->write_avail++] = c;
2824 if (c != '\n')
2825 continue;
2826 cp0[head->write_avail - 1] = '\0';
2827 head->write_avail = 0;
2828 tomoyo_normalize_line(cp0);
2829 head->write(head);
2830 }
2831 mutex_unlock(&head->io_sem);
2832 return error;
2833}
2834
2835/**
2836 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2837 *
2838 * @file: Pointer to "struct file".
2839 *
2840 * Releases memory and returns 0.
fdb8ebb7
TH
2841 *
2842 * Caller looses tomoyo_read_lock().
9590837b
KT
2843 */
2844static int tomoyo_close_control(struct file *file)
2845{
2846 struct tomoyo_io_buffer *head = file->private_data;
847b173e 2847 const bool is_write = !!head->write_buf;
9590837b 2848
17fcfbd9
TH
2849 /*
2850 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2851 * observer counter.
2852 */
2853 if (head->type == TOMOYO_QUERY)
2854 atomic_dec(&tomoyo_query_observers);
2855 else
2856 tomoyo_read_unlock(head->reader_idx);
9590837b 2857 /* Release memory used for policy I/O. */
8e2d39a1 2858 kfree(head->read_buf);
9590837b 2859 head->read_buf = NULL;
8e2d39a1 2860 kfree(head->write_buf);
9590837b 2861 head->write_buf = NULL;
8e2d39a1 2862 kfree(head);
9590837b
KT
2863 head = NULL;
2864 file->private_data = NULL;
847b173e
TH
2865 if (is_write)
2866 tomoyo_run_gc();
9590837b
KT
2867 return 0;
2868}
2869
9590837b
KT
2870/**
2871 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
2872 *
2873 * @inode: Pointer to "struct inode".
2874 * @file: Pointer to "struct file".
2875 *
2876 * Returns 0 on success, negative value otherwise.
2877 */
2878static int tomoyo_open(struct inode *inode, struct file *file)
2879{
2880 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private)
2881 - ((u8 *) NULL);
2882 return tomoyo_open_control(key, file);
2883}
2884
2885/**
2886 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
2887 *
2888 * @inode: Pointer to "struct inode".
2889 * @file: Pointer to "struct file".
2890 *
2891 * Returns 0 on success, negative value otherwise.
2892 */
2893static int tomoyo_release(struct inode *inode, struct file *file)
2894{
2895 return tomoyo_close_control(file);
2896}
2897
2898/**
2899 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface.
2900 *
2901 * @file: Pointer to "struct file".
2902 * @buf: Pointer to buffer.
2903 * @count: Size of @buf.
2904 * @ppos: Unused.
2905 *
2906 * Returns bytes read on success, negative value otherwise.
2907 */
2908static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
2909 loff_t *ppos)
2910{
2911 return tomoyo_read_control(file, buf, count);
2912}
2913
2914/**
2915 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface.
2916 *
2917 * @file: Pointer to "struct file".
2918 * @buf: Pointer to buffer.
2919 * @count: Size of @buf.
2920 * @ppos: Unused.
2921 *
2922 * Returns @count on success, negative value otherwise.
2923 */
2924static ssize_t tomoyo_write(struct file *file, const char __user *buf,
2925 size_t count, loff_t *ppos)
2926{
2927 return tomoyo_write_control(file, buf, count);
2928}
2929
c3fa109a
TH
2930/*
2931 * tomoyo_operations is a "struct file_operations" which is used for handling
2932 * /sys/kernel/security/tomoyo/ interface.
2933 *
2934 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
2935 * See tomoyo_io_buffer for internals.
2936 */
9590837b
KT
2937static const struct file_operations tomoyo_operations = {
2938 .open = tomoyo_open,
2939 .release = tomoyo_release,
2940 .read = tomoyo_read,
2941 .write = tomoyo_write,
2942};
2943
2944/**
2945 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory.
2946 *
2947 * @name: The name of the interface file.
2948 * @mode: The permission of the interface file.
2949 * @parent: The parent directory.
2950 * @key: Type of interface.
2951 *
2952 * Returns nothing.
2953 */
2954static void __init tomoyo_create_entry(const char *name, const mode_t mode,
2955 struct dentry *parent, const u8 key)
2956{
2957 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
2958 &tomoyo_operations);
2959}
2960
2961/**
2962 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
2963 *
2964 * Returns 0.
2965 */
2966static int __init tomoyo_initerface_init(void)
2967{
2968 struct dentry *tomoyo_dir;
2969
e5a3b95f
TH
2970 /* Don't create securityfs entries unless registered. */
2971 if (current_cred()->security != &tomoyo_kernel_domain)
2972 return 0;
2973
9590837b 2974 tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
17fcfbd9
TH
2975 tomoyo_create_entry("query", 0600, tomoyo_dir,
2976 TOMOYO_QUERY);
9590837b
KT
2977 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir,
2978 TOMOYO_DOMAINPOLICY);
2979 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
2980 TOMOYO_EXCEPTIONPOLICY);
2981 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
2982 TOMOYO_SELFDOMAIN);
2983 tomoyo_create_entry(".domain_status", 0600, tomoyo_dir,
2984 TOMOYO_DOMAIN_STATUS);
2985 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
2986 TOMOYO_PROCESS_STATUS);
2987 tomoyo_create_entry("meminfo", 0600, tomoyo_dir,
2988 TOMOYO_MEMINFO);
2989 tomoyo_create_entry("profile", 0600, tomoyo_dir,
2990 TOMOYO_PROFILE);
2991 tomoyo_create_entry("manager", 0600, tomoyo_dir,
2992 TOMOYO_MANAGER);
2993 tomoyo_create_entry("version", 0400, tomoyo_dir,
2994 TOMOYO_VERSION);
2995 return 0;
2996}
2997
2998fs_initcall(tomoyo_initerface_init);