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