aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c60
-rw-r--r--security/tomoyo/common.h93
-rw-r--r--security/tomoyo/domain.c13
-rw-r--r--security/tomoyo/file.c368
-rw-r--r--security/tomoyo/gc.c30
-rw-r--r--security/tomoyo/mount.c5
-rw-r--r--security/tomoyo/tomoyo.c14
-rw-r--r--security/tomoyo/util.c23
8 files changed, 71 insertions, 535 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a0d09e56874b..0776173b7d2b 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -39,13 +39,13 @@ static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
39 [TOMOYO_MAC_FILE_OPEN] = "file::open", 39 [TOMOYO_MAC_FILE_OPEN] = "file::open",
40 [TOMOYO_MAC_FILE_CREATE] = "file::create", 40 [TOMOYO_MAC_FILE_CREATE] = "file::create",
41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink", 41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink",
42 [TOMOYO_MAC_FILE_GETATTR] = "file::getattr",
42 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir", 43 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir",
43 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir", 44 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir",
44 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo", 45 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo",
45 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock", 46 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock",
46 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate", 47 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate",
47 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink", 48 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink",
48 [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite",
49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock", 49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock",
50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar", 50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar",
51 [TOMOYO_MAC_FILE_LINK] = "file::link", 51 [TOMOYO_MAC_FILE_LINK] = "file::link",
@@ -881,10 +881,6 @@ static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
881 domain->profile = (u8) profile; 881 domain->profile = (u8) profile;
882 return 0; 882 return 0;
883 } 883 }
884 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
885 domain->ignore_global_allow_read = !is_delete;
886 return 0;
887 }
888 if (!strcmp(data, TOMOYO_KEYWORD_QUOTA_EXCEEDED)) { 884 if (!strcmp(data, TOMOYO_KEYWORD_QUOTA_EXCEEDED)) {
889 domain->quota_warned = !is_delete; 885 domain->quota_warned = !is_delete;
890 return 0; 886 return 0;
@@ -942,11 +938,6 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
942 if (head->r.print_execute_only && 938 if (head->r.print_execute_only &&
943 bit != TOMOYO_TYPE_EXECUTE) 939 bit != TOMOYO_TYPE_EXECUTE)
944 continue; 940 continue;
945 /* Print "read/write" instead of "read" and "write". */
946 if ((bit == TOMOYO_TYPE_READ ||
947 bit == TOMOYO_TYPE_WRITE)
948 && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
949 continue;
950 break; 941 break;
951 } 942 }
952 if (bit >= TOMOYO_MAX_PATH_OPERATION) 943 if (bit >= TOMOYO_MAX_PATH_OPERATION)
@@ -1055,10 +1046,6 @@ static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1055 tomoyo_set_string(head, "quota_exceeded\n"); 1046 tomoyo_set_string(head, "quota_exceeded\n");
1056 if (domain->transition_failed) 1047 if (domain->transition_failed)
1057 tomoyo_set_string(head, "transition_failed\n"); 1048 tomoyo_set_string(head, "transition_failed\n");
1058 if (domain->ignore_global_allow_read)
1059 tomoyo_set_string(head,
1060 TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
1061 "\n");
1062 head->r.step++; 1049 head->r.step++;
1063 tomoyo_set_lf(head); 1050 tomoyo_set_lf(head);
1064 /* fall through */ 1051 /* fall through */
@@ -1235,18 +1222,15 @@ static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1235 static const struct { 1222 static const struct {
1236 const char *keyword; 1223 const char *keyword;
1237 int (*write) (char *, const bool); 1224 int (*write) (char *, const bool);
1238 } tomoyo_callback[4] = { 1225 } tomoyo_callback[1] = {
1239 { TOMOYO_KEYWORD_AGGREGATOR, tomoyo_write_aggregator }, 1226 { TOMOYO_KEYWORD_AGGREGATOR, tomoyo_write_aggregator },
1240 { TOMOYO_KEYWORD_FILE_PATTERN, tomoyo_write_pattern },
1241 { TOMOYO_KEYWORD_DENY_REWRITE, tomoyo_write_no_rewrite },
1242 { TOMOYO_KEYWORD_ALLOW_READ, tomoyo_write_globally_readable },
1243 }; 1227 };
1244 1228
1245 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1229 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
1246 if (tomoyo_str_starts(&data, tomoyo_transition_type[i])) 1230 if (tomoyo_str_starts(&data, tomoyo_transition_type[i]))
1247 return tomoyo_write_transition_control(data, is_delete, 1231 return tomoyo_write_transition_control(data, is_delete,
1248 i); 1232 i);
1249 for (i = 0; i < 4; i++) 1233 for (i = 0; i < 1; i++)
1250 if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword)) 1234 if (tomoyo_str_starts(&data, tomoyo_callback[i].keyword))
1251 return tomoyo_callback[i].write(data, is_delete); 1235 return tomoyo_callback[i].write(data, is_delete);
1252 for (i = 0; i < TOMOYO_MAX_GROUP; i++) 1236 for (i = 0; i < TOMOYO_MAX_GROUP; i++)
@@ -1336,15 +1320,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1336 name); 1320 name);
1337 } 1321 }
1338 break; 1322 break;
1339 case TOMOYO_ID_GLOBALLY_READABLE:
1340 {
1341 struct tomoyo_readable_file *ptr =
1342 container_of(acl, typeof(*ptr), head);
1343 tomoyo_set_string(head,
1344 TOMOYO_KEYWORD_ALLOW_READ);
1345 tomoyo_set_string(head, ptr->filename->name);
1346 }
1347 break;
1348 case TOMOYO_ID_AGGREGATOR: 1323 case TOMOYO_ID_AGGREGATOR:
1349 { 1324 {
1350 struct tomoyo_aggregator *ptr = 1325 struct tomoyo_aggregator *ptr =
@@ -1358,24 +1333,6 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1358 ptr->aggregated_name->name); 1333 ptr->aggregated_name->name);
1359 } 1334 }
1360 break; 1335 break;
1361 case TOMOYO_ID_PATTERN:
1362 {
1363 struct tomoyo_no_pattern *ptr =
1364 container_of(acl, typeof(*ptr), head);
1365 tomoyo_set_string(head,
1366 TOMOYO_KEYWORD_FILE_PATTERN);
1367 tomoyo_set_string(head, ptr->pattern->name);
1368 }
1369 break;
1370 case TOMOYO_ID_NO_REWRITE:
1371 {
1372 struct tomoyo_no_rewrite *ptr =
1373 container_of(acl, typeof(*ptr), head);
1374 tomoyo_set_string(head,
1375 TOMOYO_KEYWORD_DENY_REWRITE);
1376 tomoyo_set_string(head, ptr->pattern->name);
1377 }
1378 break;
1379 default: 1336 default:
1380 continue; 1337 continue;
1381 } 1338 }
@@ -1891,21 +1848,12 @@ int tomoyo_open_control(const u8 type, struct file *file)
1891 head->reader_idx = tomoyo_read_lock(); 1848 head->reader_idx = tomoyo_read_lock();
1892 file->private_data = head; 1849 file->private_data = head;
1893 /* 1850 /*
1894 * Call the handler now if the file is
1895 * /sys/kernel/security/tomoyo/self_domain
1896 * so that the user can use
1897 * cat < /sys/kernel/security/tomoyo/self_domain"
1898 * to know the current process's domainname.
1899 */
1900 if (type == TOMOYO_SELFDOMAIN)
1901 tomoyo_read_control(file, NULL, 0);
1902 /*
1903 * If the file is /sys/kernel/security/tomoyo/query , increment the 1851 * If the file is /sys/kernel/security/tomoyo/query , increment the
1904 * observer counter. 1852 * observer counter.
1905 * The obserber counter is used by tomoyo_supervisor() to see if 1853 * The obserber counter is used by tomoyo_supervisor() to see if
1906 * there is some process monitoring /sys/kernel/security/tomoyo/query. 1854 * there is some process monitoring /sys/kernel/security/tomoyo/query.
1907 */ 1855 */
1908 else if (type == TOMOYO_QUERY) 1856 if (type == TOMOYO_QUERY)
1909 atomic_inc(&tomoyo_query_observers); 1857 atomic_inc(&tomoyo_query_observers);
1910 return 0; 1858 return 0;
1911} 1859}
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 7c66bd898782..a5d6e212b18f 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -52,9 +52,6 @@ enum tomoyo_policy_id {
52 TOMOYO_ID_NUMBER_GROUP, 52 TOMOYO_ID_NUMBER_GROUP,
53 TOMOYO_ID_TRANSITION_CONTROL, 53 TOMOYO_ID_TRANSITION_CONTROL,
54 TOMOYO_ID_AGGREGATOR, 54 TOMOYO_ID_AGGREGATOR,
55 TOMOYO_ID_GLOBALLY_READABLE,
56 TOMOYO_ID_PATTERN,
57 TOMOYO_ID_NO_REWRITE,
58 TOMOYO_ID_MANAGER, 55 TOMOYO_ID_MANAGER,
59 TOMOYO_ID_NAME, 56 TOMOYO_ID_NAME,
60 TOMOYO_ID_ACL, 57 TOMOYO_ID_ACL,
@@ -73,8 +70,6 @@ enum tomoyo_group_id {
73#define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount " 70#define TOMOYO_KEYWORD_ALLOW_MOUNT "allow_mount "
74#define TOMOYO_KEYWORD_ALLOW_READ "allow_read " 71#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
75#define TOMOYO_KEYWORD_DELETE "delete " 72#define TOMOYO_KEYWORD_DELETE "delete "
76#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
77#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
78#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain " 73#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
79#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain " 74#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
80#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " 75#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
@@ -83,7 +78,6 @@ enum tomoyo_group_id {
83#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group " 78#define TOMOYO_KEYWORD_NUMBER_GROUP "number_group "
84#define TOMOYO_KEYWORD_SELECT "select " 79#define TOMOYO_KEYWORD_SELECT "select "
85#define TOMOYO_KEYWORD_USE_PROFILE "use_profile " 80#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
86#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
87#define TOMOYO_KEYWORD_QUOTA_EXCEEDED "quota_exceeded" 81#define TOMOYO_KEYWORD_QUOTA_EXCEEDED "quota_exceeded"
88#define TOMOYO_KEYWORD_TRANSITION_FAILED "transition_failed" 82#define TOMOYO_KEYWORD_TRANSITION_FAILED "transition_failed"
89/* A domain definition starts with <kernel>. */ 83/* A domain definition starts with <kernel>. */
@@ -115,35 +109,21 @@ enum tomoyo_acl_entry_type_index {
115}; 109};
116 110
117/* Index numbers for File Controls. */ 111/* Index numbers for File Controls. */
118
119/*
120 * TOMOYO_TYPE_READ_WRITE is special. TOMOYO_TYPE_READ_WRITE is automatically
121 * set if both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are set.
122 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically set if
123 * TOMOYO_TYPE_READ_WRITE is set.
124 * TOMOYO_TYPE_READ_WRITE is automatically cleared if either TOMOYO_TYPE_READ
125 * or TOMOYO_TYPE_WRITE is cleared.
126 * Both TOMOYO_TYPE_READ and TOMOYO_TYPE_WRITE are automatically cleared if
127 * TOMOYO_TYPE_READ_WRITE is cleared.
128 */
129
130enum tomoyo_path_acl_index { 112enum tomoyo_path_acl_index {
131 TOMOYO_TYPE_READ_WRITE,
132 TOMOYO_TYPE_EXECUTE, 113 TOMOYO_TYPE_EXECUTE,
133 TOMOYO_TYPE_READ, 114 TOMOYO_TYPE_READ,
134 TOMOYO_TYPE_WRITE, 115 TOMOYO_TYPE_WRITE,
116 TOMOYO_TYPE_APPEND,
135 TOMOYO_TYPE_UNLINK, 117 TOMOYO_TYPE_UNLINK,
118 TOMOYO_TYPE_GETATTR,
136 TOMOYO_TYPE_RMDIR, 119 TOMOYO_TYPE_RMDIR,
137 TOMOYO_TYPE_TRUNCATE, 120 TOMOYO_TYPE_TRUNCATE,
138 TOMOYO_TYPE_SYMLINK, 121 TOMOYO_TYPE_SYMLINK,
139 TOMOYO_TYPE_REWRITE,
140 TOMOYO_TYPE_CHROOT, 122 TOMOYO_TYPE_CHROOT,
141 TOMOYO_TYPE_UMOUNT, 123 TOMOYO_TYPE_UMOUNT,
142 TOMOYO_MAX_PATH_OPERATION 124 TOMOYO_MAX_PATH_OPERATION
143}; 125};
144 126
145#define TOMOYO_RW_MASK ((1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE))
146
147enum tomoyo_mkdev_acl_index { 127enum tomoyo_mkdev_acl_index {
148 TOMOYO_TYPE_MKBLOCK, 128 TOMOYO_TYPE_MKBLOCK,
149 TOMOYO_TYPE_MKCHAR, 129 TOMOYO_TYPE_MKCHAR,
@@ -187,13 +167,13 @@ enum tomoyo_mac_index {
187 TOMOYO_MAC_FILE_OPEN, 167 TOMOYO_MAC_FILE_OPEN,
188 TOMOYO_MAC_FILE_CREATE, 168 TOMOYO_MAC_FILE_CREATE,
189 TOMOYO_MAC_FILE_UNLINK, 169 TOMOYO_MAC_FILE_UNLINK,
170 TOMOYO_MAC_FILE_GETATTR,
190 TOMOYO_MAC_FILE_MKDIR, 171 TOMOYO_MAC_FILE_MKDIR,
191 TOMOYO_MAC_FILE_RMDIR, 172 TOMOYO_MAC_FILE_RMDIR,
192 TOMOYO_MAC_FILE_MKFIFO, 173 TOMOYO_MAC_FILE_MKFIFO,
193 TOMOYO_MAC_FILE_MKSOCK, 174 TOMOYO_MAC_FILE_MKSOCK,
194 TOMOYO_MAC_FILE_TRUNCATE, 175 TOMOYO_MAC_FILE_TRUNCATE,
195 TOMOYO_MAC_FILE_SYMLINK, 176 TOMOYO_MAC_FILE_SYMLINK,
196 TOMOYO_MAC_FILE_REWRITE,
197 TOMOYO_MAC_FILE_MKBLOCK, 177 TOMOYO_MAC_FILE_MKBLOCK,
198 TOMOYO_MAC_FILE_MKCHAR, 178 TOMOYO_MAC_FILE_MKCHAR,
199 TOMOYO_MAC_FILE_LINK, 179 TOMOYO_MAC_FILE_LINK,
@@ -388,9 +368,7 @@ struct tomoyo_acl_info {
388 * "deleted", false otherwise. 368 * "deleted", false otherwise.
389 * (6) "quota_warned" is a bool which is used for suppressing warning message 369 * (6) "quota_warned" is a bool which is used for suppressing warning message
390 * when learning mode learned too much entries. 370 * when learning mode learned too much entries.
391 * (7) "ignore_global_allow_read" is a bool which is true if this domain 371 * (7) "transition_failed" is a bool which is set to true when this domain was
392 * should ignore "allow_read" directive in exception policy.
393 * (8) "transition_failed" is a bool which is set to true when this domain was
394 * unable to create a new domain at tomoyo_find_next_domain() because the 372 * unable to create a new domain at tomoyo_find_next_domain() because the
395 * name of the domain to be created was too long or it could not allocate 373 * name of the domain to be created was too long or it could not allocate
396 * memory. If set to true, more than one process continued execve() 374 * memory. If set to true, more than one process continued execve()
@@ -415,7 +393,6 @@ struct tomoyo_domain_info {
415 u8 profile; /* Profile number to use. */ 393 u8 profile; /* Profile number to use. */
416 bool is_deleted; /* Delete flag. */ 394 bool is_deleted; /* Delete flag. */
417 bool quota_warned; /* Quota warnning flag. */ 395 bool quota_warned; /* Quota warnning flag. */
418 bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
419 bool transition_failed; /* Domain transition failed flag. */ 396 bool transition_failed; /* Domain transition failed flag. */
420 atomic_t users; /* Number of referring credentials. */ 397 atomic_t users; /* Number of referring credentials. */
421}; 398};
@@ -429,10 +406,9 @@ struct tomoyo_domain_info {
429 * (2) "perm" which is a bitmask of permitted operations. 406 * (2) "perm" which is a bitmask of permitted operations.
430 * (3) "name" is the pathname. 407 * (3) "name" is the pathname.
431 * 408 *
432 * Directives held by this structure are "allow_read/write", "allow_execute", 409 * Directives held by this structure are "allow_execute", "allow_read",
433 * "allow_read", "allow_write", "allow_unlink", "allow_rmdir", 410 * "allow_write", "allow_append", "allow_unlink", "allow_rmdir",
434 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_chroot" and 411 * "allow_truncate", "allow_symlink", "allow_chroot" and "allow_unmount".
435 * "allow_unmount".
436 */ 412 */
437struct tomoyo_path_acl { 413struct tomoyo_path_acl {
438 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */ 414 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
@@ -574,47 +550,6 @@ struct tomoyo_io_buffer {
574}; 550};
575 551
576/* 552/*
577 * tomoyo_readable_file is a structure which is used for holding
578 * "allow_read" entries.
579 * It has following fields.
580 *
581 * (1) "head" is "struct tomoyo_acl_head".
582 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
583 */
584struct tomoyo_readable_file {
585 struct tomoyo_acl_head head;
586 const struct tomoyo_path_info *filename;
587};
588
589/*
590 * tomoyo_no_pattern is a structure which is used for holding
591 * "file_pattern" entries.
592 * It has following fields.
593 *
594 * (1) "head" is "struct tomoyo_acl_head".
595 * (2) "pattern" is a pathname pattern which is used for converting pathnames
596 * to pathname patterns during learning mode.
597 */
598struct tomoyo_no_pattern {
599 struct tomoyo_acl_head head;
600 const struct tomoyo_path_info *pattern;
601};
602
603/*
604 * tomoyo_no_rewrite is a structure which is used for holding
605 * "deny_rewrite" entries.
606 * It has following fields.
607 *
608 * (1) "head" is "struct tomoyo_acl_head".
609 * (2) "pattern" is a pathname which is by default not permitted to modify
610 * already existing content.
611 */
612struct tomoyo_no_rewrite {
613 struct tomoyo_acl_head head;
614 const struct tomoyo_path_info *pattern;
615};
616
617/*
618 * tomoyo_transition_control is a structure which is used for holding 553 * tomoyo_transition_control is a structure which is used for holding
619 * "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain" 554 * "initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain"
620 * entries. 555 * entries.
@@ -764,23 +699,17 @@ int tomoyo_write_aggregator(char *data, const bool is_delete);
764int tomoyo_write_transition_control(char *data, const bool is_delete, 699int tomoyo_write_transition_control(char *data, const bool is_delete,
765 const u8 type); 700 const u8 type);
766/* 701/*
767 * Create "allow_read/write", "allow_execute", "allow_read", "allow_write", 702 * Create "allow_execute", "allow_read", "allow_write", "allow_append",
768 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir", 703 * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
769 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar", 704 * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
770 * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and 705 * "allow_truncate", "allow_symlink", "allow_rename" and "allow_link" entry
771 * "allow_link" entry in domain policy. 706 * in domain policy.
772 */ 707 */
773int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain, 708int tomoyo_write_file(char *data, struct tomoyo_domain_info *domain,
774 const bool is_delete); 709 const bool is_delete);
775/* Create "allow_read" entry in exception policy. */
776int tomoyo_write_globally_readable(char *data, const bool is_delete);
777/* Create "allow_mount" entry in domain policy. */ 710/* Create "allow_mount" entry in domain policy. */
778int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain, 711int tomoyo_write_mount(char *data, struct tomoyo_domain_info *domain,
779 const bool is_delete); 712 const bool is_delete);
780/* Create "deny_rewrite" entry in exception policy. */
781int tomoyo_write_no_rewrite(char *data, const bool is_delete);
782/* Create "file_pattern" entry in exception policy. */
783int tomoyo_write_pattern(char *data, const bool is_delete);
784/* Create "path_group"/"number_group" entry in exception policy. */ 713/* Create "path_group"/"number_group" entry in exception policy. */
785int tomoyo_write_group(char *data, const bool is_delete, const u8 type); 714int tomoyo_write_group(char *data, const bool is_delete, const u8 type);
786int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 715int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
@@ -819,8 +748,6 @@ char *tomoyo_realpath_nofollow(const char *pathname);
819 * ignores chroot'ed root and the pathname is already solved. 748 * ignores chroot'ed root and the pathname is already solved.
820 */ 749 */
821char *tomoyo_realpath_from_path(struct path *path); 750char *tomoyo_realpath_from_path(struct path *path);
822/* Get patterned pathname. */
823const char *tomoyo_pattern(const struct tomoyo_path_info *filename);
824 751
825/* Check memory quota. */ 752/* Check memory quota. */
826bool tomoyo_memory_ok(void *ptr); 753bool tomoyo_memory_ok(void *ptr);
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 35388408e475..355b536262b1 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -510,17 +510,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
510 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10) 510 if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
511 goto done; 511 goto done;
512 domain = tomoyo_find_domain(tmp); 512 domain = tomoyo_find_domain(tmp);
513 if (domain) 513 if (!domain)
514 goto done; 514 domain = tomoyo_assign_domain(tmp, old_domain->profile);
515 if (is_enforce) {
516 int error = tomoyo_supervisor(&r, "# wants to create domain\n"
517 "%s\n", tmp);
518 if (error == TOMOYO_RETRY_REQUEST)
519 goto retry;
520 if (error < 0)
521 goto done;
522 }
523 domain = tomoyo_assign_domain(tmp, old_domain->profile);
524 done: 515 done:
525 if (domain) 516 if (domain)
526 goto out; 517 goto out;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index d64e8ecb6fb3..41ed7de44ef1 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -11,15 +11,15 @@
11 11
12/* Keyword array for operations with one pathname. */ 12/* Keyword array for operations with one pathname. */
13const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 13const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
14 [TOMOYO_TYPE_READ_WRITE] = "read/write",
15 [TOMOYO_TYPE_EXECUTE] = "execute", 14 [TOMOYO_TYPE_EXECUTE] = "execute",
16 [TOMOYO_TYPE_READ] = "read", 15 [TOMOYO_TYPE_READ] = "read",
17 [TOMOYO_TYPE_WRITE] = "write", 16 [TOMOYO_TYPE_WRITE] = "write",
17 [TOMOYO_TYPE_APPEND] = "append",
18 [TOMOYO_TYPE_UNLINK] = "unlink", 18 [TOMOYO_TYPE_UNLINK] = "unlink",
19 [TOMOYO_TYPE_GETATTR] = "getattr",
19 [TOMOYO_TYPE_RMDIR] = "rmdir", 20 [TOMOYO_TYPE_RMDIR] = "rmdir",
20 [TOMOYO_TYPE_TRUNCATE] = "truncate", 21 [TOMOYO_TYPE_TRUNCATE] = "truncate",
21 [TOMOYO_TYPE_SYMLINK] = "symlink", 22 [TOMOYO_TYPE_SYMLINK] = "symlink",
22 [TOMOYO_TYPE_REWRITE] = "rewrite",
23 [TOMOYO_TYPE_CHROOT] = "chroot", 23 [TOMOYO_TYPE_CHROOT] = "chroot",
24 [TOMOYO_TYPE_UMOUNT] = "unmount", 24 [TOMOYO_TYPE_UMOUNT] = "unmount",
25}; 25};
@@ -50,15 +50,15 @@ const char *tomoyo_path_number_keyword[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
50}; 50};
51 51
52static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 52static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
53 [TOMOYO_TYPE_READ_WRITE] = TOMOYO_MAC_FILE_OPEN,
54 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 53 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
55 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 54 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
56 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, 55 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
56 [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
57 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, 57 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
58 [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
58 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, 59 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
59 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, 60 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
60 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, 61 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
61 [TOMOYO_TYPE_REWRITE] = TOMOYO_MAC_FILE_REWRITE,
62 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, 62 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 63 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
64}; 64};
@@ -132,24 +132,6 @@ static void tomoyo_add_slash(struct tomoyo_path_info *buf)
132} 132}
133 133
134/** 134/**
135 * tomoyo_strendswith - Check whether the token ends with the given token.
136 *
137 * @name: The token to check.
138 * @tail: The token to find.
139 *
140 * Returns true if @name ends with @tail, false otherwise.
141 */
142static bool tomoyo_strendswith(const char *name, const char *tail)
143{
144 int len;
145
146 if (!name || !tail)
147 return false;
148 len = strlen(name) - strlen(tail);
149 return len >= 0 && !strcmp(name + len, tail);
150}
151
152/**
153 * tomoyo_get_realpath - Get realpath. 135 * tomoyo_get_realpath - Get realpath.
154 * 136 *
155 * @buf: Pointer to "struct tomoyo_path_info". 137 * @buf: Pointer to "struct tomoyo_path_info".
@@ -182,7 +164,7 @@ static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
182 return 0; 164 return 0;
183 tomoyo_warn_log(r, "%s %s", operation, filename->name); 165 tomoyo_warn_log(r, "%s %s", operation, filename->name);
184 return tomoyo_supervisor(r, "allow_%s %s\n", operation, 166 return tomoyo_supervisor(r, "allow_%s %s\n", operation,
185 tomoyo_pattern(filename)); 167 filename->name);
186} 168}
187 169
188/** 170/**
@@ -202,8 +184,7 @@ static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
202 tomoyo_warn_log(r, "%s %s %s", operation, filename1->name, 184 tomoyo_warn_log(r, "%s %s %s", operation, filename1->name,
203 filename2->name); 185 filename2->name);
204 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 186 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
205 tomoyo_pattern(filename1), 187 filename1->name, filename2->name);
206 tomoyo_pattern(filename2));
207} 188}
208 189
209/** 190/**
@@ -225,7 +206,7 @@ static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
225 tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode, 206 tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode,
226 major, minor); 207 major, minor);
227 return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation, 208 return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation,
228 tomoyo_pattern(filename), mode, major, minor); 209 filename->name, mode, major, minor);
229} 210}
230 211
231/** 212/**
@@ -264,247 +245,7 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
264 radix); 245 radix);
265 tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); 246 tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer);
266 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, 247 return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
267 tomoyo_pattern(filename), buffer); 248 filename->name, buffer);
268}
269
270static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a,
271 const struct tomoyo_acl_head *b)
272{
273 return container_of(a, struct tomoyo_readable_file,
274 head)->filename ==
275 container_of(b, struct tomoyo_readable_file,
276 head)->filename;
277}
278
279/**
280 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_readable_file" list.
281 *
282 * @filename: Filename unconditionally permitted to open() for reading.
283 * @is_delete: True if it is a delete request.
284 *
285 * Returns 0 on success, negative value otherwise.
286 *
287 * Caller holds tomoyo_read_lock().
288 */
289static int tomoyo_update_globally_readable_entry(const char *filename,
290 const bool is_delete)
291{
292 struct tomoyo_readable_file e = { };
293 int error;
294
295 if (!tomoyo_correct_word(filename))
296 return -EINVAL;
297 e.filename = tomoyo_get_name(filename);
298 if (!e.filename)
299 return -ENOMEM;
300 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
301 &tomoyo_policy_list
302 [TOMOYO_ID_GLOBALLY_READABLE],
303 tomoyo_same_globally_readable);
304 tomoyo_put_name(e.filename);
305 return error;
306}
307
308/**
309 * tomoyo_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
310 *
311 * @filename: The filename to check.
312 *
313 * Returns true if any domain can open @filename for reading, false otherwise.
314 *
315 * Caller holds tomoyo_read_lock().
316 */
317static bool tomoyo_globally_readable_file(const struct tomoyo_path_info *
318 filename)
319{
320 struct tomoyo_readable_file *ptr;
321 bool found = false;
322
323 list_for_each_entry_rcu(ptr, &tomoyo_policy_list
324 [TOMOYO_ID_GLOBALLY_READABLE], head.list) {
325 if (!ptr->head.is_deleted &&
326 tomoyo_path_matches_pattern(filename, ptr->filename)) {
327 found = true;
328 break;
329 }
330 }
331 return found;
332}
333
334/**
335 * tomoyo_write_globally_readable - Write "struct tomoyo_readable_file" list.
336 *
337 * @data: String to parse.
338 * @is_delete: True if it is a delete request.
339 *
340 * Returns 0 on success, negative value otherwise.
341 *
342 * Caller holds tomoyo_read_lock().
343 */
344int tomoyo_write_globally_readable(char *data, const bool is_delete)
345{
346 return tomoyo_update_globally_readable_entry(data, is_delete);
347}
348
349static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a,
350 const struct tomoyo_acl_head *b)
351{
352 return container_of(a, struct tomoyo_no_pattern, head)->pattern ==
353 container_of(b, struct tomoyo_no_pattern, head)->pattern;
354}
355
356/**
357 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_no_pattern" list.
358 *
359 * @pattern: Pathname pattern.
360 * @is_delete: True if it is a delete request.
361 *
362 * Returns 0 on success, negative value otherwise.
363 *
364 * Caller holds tomoyo_read_lock().
365 */
366static int tomoyo_update_file_pattern_entry(const char *pattern,
367 const bool is_delete)
368{
369 struct tomoyo_no_pattern e = { };
370 int error;
371
372 if (!tomoyo_correct_word(pattern))
373 return -EINVAL;
374 e.pattern = tomoyo_get_name(pattern);
375 if (!e.pattern)
376 return -ENOMEM;
377 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
378 &tomoyo_policy_list[TOMOYO_ID_PATTERN],
379 tomoyo_same_pattern);
380 tomoyo_put_name(e.pattern);
381 return error;
382}
383
384/**
385 * tomoyo_pattern - Get patterned pathname.
386 *
387 * @filename: The filename to find patterned pathname.
388 *
389 * Returns pointer to pathname pattern if matched, @filename otherwise.
390 *
391 * Caller holds tomoyo_read_lock().
392 */
393const char *tomoyo_pattern(const struct tomoyo_path_info *filename)
394{
395 struct tomoyo_no_pattern *ptr;
396 const struct tomoyo_path_info *pattern = NULL;
397
398 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN],
399 head.list) {
400 if (ptr->head.is_deleted)
401 continue;
402 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
403 continue;
404 pattern = ptr->pattern;
405 if (tomoyo_strendswith(pattern->name, "/\\*")) {
406 /* Do nothing. Try to find the better match. */
407 } else {
408 /* This would be the better match. Use this. */
409 break;
410 }
411 }
412 if (pattern)
413 filename = pattern;
414 return filename->name;
415}
416
417/**
418 * tomoyo_write_pattern - Write "struct tomoyo_no_pattern" list.
419 *
420 * @data: String to parse.
421 * @is_delete: True if it is a delete request.
422 *
423 * Returns 0 on success, negative value otherwise.
424 *
425 * Caller holds tomoyo_read_lock().
426 */
427int tomoyo_write_pattern(char *data, const bool is_delete)
428{
429 return tomoyo_update_file_pattern_entry(data, is_delete);
430}
431
432static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a,
433 const struct tomoyo_acl_head *b)
434{
435 return container_of(a, struct tomoyo_no_rewrite, head)->pattern
436 == container_of(b, struct tomoyo_no_rewrite, head)
437 ->pattern;
438}
439
440/**
441 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite" list.
442 *
443 * @pattern: Pathname pattern that are not rewritable by default.
444 * @is_delete: True if it is a delete request.
445 *
446 * Returns 0 on success, negative value otherwise.
447 *
448 * Caller holds tomoyo_read_lock().
449 */
450static int tomoyo_update_no_rewrite_entry(const char *pattern,
451 const bool is_delete)
452{
453 struct tomoyo_no_rewrite e = { };
454 int error;
455
456 if (!tomoyo_correct_word(pattern))
457 return -EINVAL;
458 e.pattern = tomoyo_get_name(pattern);
459 if (!e.pattern)
460 return -ENOMEM;
461 error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
462 &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
463 tomoyo_same_no_rewrite);
464 tomoyo_put_name(e.pattern);
465 return error;
466}
467
468/**
469 * tomoyo_no_rewrite_file - Check if the given pathname is not permitted to be rewrited.
470 *
471 * @filename: Filename to check.
472 *
473 * Returns true if @filename is specified by "deny_rewrite" directive,
474 * false otherwise.
475 *
476 * Caller holds tomoyo_read_lock().
477 */
478static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename)
479{
480 struct tomoyo_no_rewrite *ptr;
481 bool found = false;
482
483 list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE],
484 head.list) {
485 if (ptr->head.is_deleted)
486 continue;
487 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
488 continue;
489 found = true;
490 break;
491 }
492 return found;
493}
494
495/**
496 * tomoyo_write_no_rewrite - Write "struct tomoyo_no_rewrite" list.
497 *
498 * @data: String to parse.
499 * @is_delete: True if it is a delete request.
500 *
501 * Returns 0 on success, negative value otherwise.
502 *
503 * Caller holds tomoyo_read_lock().
504 */
505int tomoyo_write_no_rewrite(char *data, const bool is_delete)
506{
507 return tomoyo_update_no_rewrite_entry(data, is_delete);
508} 249}
509 250
510static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 251static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
@@ -569,6 +310,15 @@ static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
569 tomoyo_same_name_union(&p1->name, &p2->name); 310 tomoyo_same_name_union(&p1->name, &p2->name);
570} 311}
571 312
313/**
314 * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
315 *
316 * @a: Pointer to "struct tomoyo_acl_info".
317 * @b: Pointer to "struct tomoyo_acl_info".
318 * @is_delete: True for @a &= ~@b, false for @a |= @b.
319 *
320 * Returns true if @a is empty, false otherwise.
321 */
572static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, 322static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
573 struct tomoyo_acl_info *b, 323 struct tomoyo_acl_info *b,
574 const bool is_delete) 324 const bool is_delete)
@@ -577,19 +327,10 @@ static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
577 ->perm; 327 ->perm;
578 u16 perm = *a_perm; 328 u16 perm = *a_perm;
579 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; 329 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
580 if (is_delete) { 330 if (is_delete)
581 perm &= ~b_perm; 331 perm &= ~b_perm;
582 if ((perm & TOMOYO_RW_MASK) != TOMOYO_RW_MASK) 332 else
583 perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
584 else if (!(perm & (1 << TOMOYO_TYPE_READ_WRITE)))
585 perm &= ~TOMOYO_RW_MASK;
586 } else {
587 perm |= b_perm; 333 perm |= b_perm;
588 if ((perm & TOMOYO_RW_MASK) == TOMOYO_RW_MASK)
589 perm |= (1 << TOMOYO_TYPE_READ_WRITE);
590 else if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
591 perm |= TOMOYO_RW_MASK;
592 }
593 *a_perm = perm; 334 *a_perm = perm;
594 return !perm; 335 return !perm;
595} 336}
@@ -615,8 +356,6 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
615 .perm = 1 << type 356 .perm = 1 << type
616 }; 357 };
617 int error; 358 int error;
618 if (e.perm == (1 << TOMOYO_TYPE_READ_WRITE))
619 e.perm |= TOMOYO_RW_MASK;
620 if (!tomoyo_parse_name_union(filename, &e.name)) 359 if (!tomoyo_parse_name_union(filename, &e.name))
621 return -EINVAL; 360 return -EINVAL;
622 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain, 361 error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain,
@@ -775,7 +514,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
775{ 514{
776 int error; 515 int error;
777 516
778 next:
779 r->type = tomoyo_p2mac[operation]; 517 r->type = tomoyo_p2mac[operation];
780 r->mode = tomoyo_get_mode(r->profile, r->type); 518 r->mode = tomoyo_get_mode(r->profile, r->type);
781 if (r->mode == TOMOYO_CONFIG_DISABLED) 519 if (r->mode == TOMOYO_CONFIG_DISABLED)
@@ -785,10 +523,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
785 r->param.path.operation = operation; 523 r->param.path.operation = operation;
786 do { 524 do {
787 tomoyo_check_acl(r, tomoyo_check_path_acl); 525 tomoyo_check_acl(r, tomoyo_check_path_acl);
788 if (!r->granted && operation == TOMOYO_TYPE_READ &&
789 !r->domain->ignore_global_allow_read &&
790 tomoyo_globally_readable_file(filename))
791 r->granted = true;
792 error = tomoyo_audit_path_log(r); 526 error = tomoyo_audit_path_log(r);
793 /* 527 /*
794 * Do not retry for execute request, for alias may have 528 * Do not retry for execute request, for alias may have
@@ -796,16 +530,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
796 */ 530 */
797 } while (error == TOMOYO_RETRY_REQUEST && 531 } while (error == TOMOYO_RETRY_REQUEST &&
798 operation != TOMOYO_TYPE_EXECUTE); 532 operation != TOMOYO_TYPE_EXECUTE);
799 /*
800 * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
801 * we need to check "allow_rewrite" permission if the filename is
802 * specified by "deny_rewrite" keyword.
803 */
804 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
805 tomoyo_no_rewrite_file(filename)) {
806 operation = TOMOYO_TYPE_REWRITE;
807 goto next;
808 }
809 return error; 533 return error;
810} 534}
811 535
@@ -932,43 +656,26 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
932 struct tomoyo_request_info r; 656 struct tomoyo_request_info r;
933 int idx; 657 int idx;
934 658
935 if (!path->mnt || 659 if (!path->mnt)
936 (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
937 return 0; 660 return 0;
938 buf.name = NULL; 661 buf.name = NULL;
939 r.mode = TOMOYO_CONFIG_DISABLED; 662 r.mode = TOMOYO_CONFIG_DISABLED;
940 idx = tomoyo_read_lock(); 663 idx = tomoyo_read_lock();
941 /* 664 if (acc_mode &&
942 * If the filename is specified by "deny_rewrite" keyword, 665 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
943 * we need to check "allow_rewrite" permission when the filename is not
944 * opened for append mode or the filename is truncated at open time.
945 */
946 if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND)
947 && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE)
948 != TOMOYO_CONFIG_DISABLED) { 666 != TOMOYO_CONFIG_DISABLED) {
949 if (!tomoyo_get_realpath(&buf, path)) { 667 if (!tomoyo_get_realpath(&buf, path)) {
950 error = -ENOMEM; 668 error = -ENOMEM;
951 goto out; 669 goto out;
952 } 670 }
953 if (tomoyo_no_rewrite_file(&buf)) 671 if (acc_mode & MAY_READ)
954 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, 672 error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
673 &buf);
674 if (!error && (acc_mode & MAY_WRITE))
675 error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
676 TOMOYO_TYPE_APPEND :
677 TOMOYO_TYPE_WRITE,
955 &buf); 678 &buf);
956 }
957 if (!error && acc_mode &&
958 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
959 != TOMOYO_CONFIG_DISABLED) {
960 u8 operation;
961 if (!buf.name && !tomoyo_get_realpath(&buf, path)) {
962 error = -ENOMEM;
963 goto out;
964 }
965 if (acc_mode == (MAY_READ | MAY_WRITE))
966 operation = TOMOYO_TYPE_READ_WRITE;
967 else if (acc_mode == MAY_READ)
968 operation = TOMOYO_TYPE_READ;
969 else
970 operation = TOMOYO_TYPE_WRITE;
971 error = tomoyo_path_permission(&r, operation, &buf);
972 } 679 }
973 out: 680 out:
974 kfree(buf.name); 681 kfree(buf.name);
@@ -979,7 +686,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
979} 686}
980 687
981/** 688/**
982 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount". 689 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
983 * 690 *
984 * @operation: Type of operation. 691 * @operation: Type of operation.
985 * @path: Pointer to "struct path". 692 * @path: Pointer to "struct path".
@@ -988,9 +695,10 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
988 */ 695 */
989int tomoyo_path_perm(const u8 operation, struct path *path) 696int tomoyo_path_perm(const u8 operation, struct path *path)
990{ 697{
991 int error = -ENOMEM;
992 struct tomoyo_path_info buf;
993 struct tomoyo_request_info r; 698 struct tomoyo_request_info r;
699 int error;
700 struct tomoyo_path_info buf;
701 bool is_enforce;
994 int idx; 702 int idx;
995 703
996 if (!path->mnt) 704 if (!path->mnt)
@@ -998,17 +706,13 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
998 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) 706 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
999 == TOMOYO_CONFIG_DISABLED) 707 == TOMOYO_CONFIG_DISABLED)
1000 return 0; 708 return 0;
709 is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
710 error = -ENOMEM;
1001 buf.name = NULL; 711 buf.name = NULL;
1002 idx = tomoyo_read_lock(); 712 idx = tomoyo_read_lock();
1003 if (!tomoyo_get_realpath(&buf, path)) 713 if (!tomoyo_get_realpath(&buf, path))
1004 goto out; 714 goto out;
1005 switch (operation) { 715 switch (operation) {
1006 case TOMOYO_TYPE_REWRITE:
1007 if (!tomoyo_no_rewrite_file(&buf)) {
1008 error = 0;
1009 goto out;
1010 }
1011 break;
1012 case TOMOYO_TYPE_RMDIR: 716 case TOMOYO_TYPE_RMDIR:
1013 case TOMOYO_TYPE_CHROOT: 717 case TOMOYO_TYPE_CHROOT:
1014 tomoyo_add_slash(&buf); 718 tomoyo_add_slash(&buf);
@@ -1018,7 +722,7 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1018 out: 722 out:
1019 kfree(buf.name); 723 kfree(buf.name);
1020 tomoyo_read_unlock(idx); 724 tomoyo_read_unlock(idx);
1021 if (r.mode != TOMOYO_CONFIG_ENFORCING) 725 if (!is_enforce)
1022 error = 0; 726 error = 0;
1023 return error; 727 return error;
1024} 728}
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index a877e4c3b101..ba799b49ee3a 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -32,27 +32,6 @@ static bool tomoyo_add_to_gc(const int type, struct list_head *element)
32 return true; 32 return true;
33} 33}
34 34
35static void tomoyo_del_allow_read(struct list_head *element)
36{
37 struct tomoyo_readable_file *ptr =
38 container_of(element, typeof(*ptr), head.list);
39 tomoyo_put_name(ptr->filename);
40}
41
42static void tomoyo_del_file_pattern(struct list_head *element)
43{
44 struct tomoyo_no_pattern *ptr =
45 container_of(element, typeof(*ptr), head.list);
46 tomoyo_put_name(ptr->pattern);
47}
48
49static void tomoyo_del_no_rewrite(struct list_head *element)
50{
51 struct tomoyo_no_rewrite *ptr =
52 container_of(element, typeof(*ptr), head.list);
53 tomoyo_put_name(ptr->pattern);
54}
55
56static void tomoyo_del_transition_control(struct list_head *element) 35static void tomoyo_del_transition_control(struct list_head *element)
57{ 36{
58 struct tomoyo_transition_control *ptr = 37 struct tomoyo_transition_control *ptr =
@@ -290,15 +269,6 @@ static void tomoyo_kfree_entry(void)
290 case TOMOYO_ID_AGGREGATOR: 269 case TOMOYO_ID_AGGREGATOR:
291 tomoyo_del_aggregator(element); 270 tomoyo_del_aggregator(element);
292 break; 271 break;
293 case TOMOYO_ID_GLOBALLY_READABLE:
294 tomoyo_del_allow_read(element);
295 break;
296 case TOMOYO_ID_PATTERN:
297 tomoyo_del_file_pattern(element);
298 break;
299 case TOMOYO_ID_NO_REWRITE:
300 tomoyo_del_no_rewrite(element);
301 break;
302 case TOMOYO_ID_MANAGER: 272 case TOMOYO_ID_MANAGER:
303 tomoyo_del_manager(element); 273 tomoyo_del_manager(element);
304 break; 274 break;
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 162a864dba24..f1d9e1a9eff4 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -55,9 +55,8 @@ static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
55 flags); 55 flags);
56 return tomoyo_supervisor(r, 56 return tomoyo_supervisor(r,
57 TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n", 57 TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
58 tomoyo_pattern(r->param.mount.dev), 58 r->param.mount.dev->name,
59 tomoyo_pattern(r->param.mount.dir), type, 59 r->param.mount.dir->name, type, flags);
60 flags);
61} 60}
62 61
63static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, 62static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 95d3f9572237..2615c7d43960 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -93,6 +93,12 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
93 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY); 93 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY);
94} 94}
95 95
96static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
97{
98 struct path path = { mnt, dentry };
99 return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path);
100}
101
96static int tomoyo_path_truncate(struct path *path) 102static int tomoyo_path_truncate(struct path *path)
97{ 103{
98 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path); 104 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path);
@@ -176,9 +182,10 @@ static int tomoyo_path_rename(struct path *old_parent,
176static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 182static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
177 unsigned long arg) 183 unsigned long arg)
178{ 184{
179 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 185 if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
180 return tomoyo_path_perm(TOMOYO_TYPE_REWRITE, &file->f_path); 186 return 0;
181 return 0; 187 return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
188 O_WRONLY | (arg & O_APPEND));
182} 189}
183 190
184static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 191static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
@@ -258,6 +265,7 @@ static struct security_operations tomoyo_security_ops = {
258 .path_mknod = tomoyo_path_mknod, 265 .path_mknod = tomoyo_path_mknod,
259 .path_link = tomoyo_path_link, 266 .path_link = tomoyo_path_link,
260 .path_rename = tomoyo_path_rename, 267 .path_rename = tomoyo_path_rename,
268 .inode_getattr = tomoyo_inode_getattr,
261 .file_ioctl = tomoyo_file_ioctl, 269 .file_ioctl = tomoyo_file_ioctl,
262 .path_chmod = tomoyo_path_chmod, 270 .path_chmod = tomoyo_path_chmod,
263 .path_chown = tomoyo_path_chown, 271 .path_chown = tomoyo_path_chown,
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 6d5393204d95..7fb9bbf7021a 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -911,44 +911,33 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
911 if (!domain) 911 if (!domain)
912 return true; 912 return true;
913 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 913 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
914 u16 perm;
915 u8 i;
914 if (ptr->is_deleted) 916 if (ptr->is_deleted)
915 continue; 917 continue;
916 switch (ptr->type) { 918 switch (ptr->type) {
917 u16 perm;
918 u8 i;
919 case TOMOYO_TYPE_PATH_ACL: 919 case TOMOYO_TYPE_PATH_ACL:
920 perm = container_of(ptr, struct tomoyo_path_acl, head) 920 perm = container_of(ptr, struct tomoyo_path_acl, head)
921 ->perm; 921 ->perm;
922 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
923 if (perm & (1 << i))
924 count++;
925 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
926 count -= 2;
927 break; 922 break;
928 case TOMOYO_TYPE_PATH2_ACL: 923 case TOMOYO_TYPE_PATH2_ACL:
929 perm = container_of(ptr, struct tomoyo_path2_acl, head) 924 perm = container_of(ptr, struct tomoyo_path2_acl, head)
930 ->perm; 925 ->perm;
931 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
932 if (perm & (1 << i))
933 count++;
934 break; 926 break;
935 case TOMOYO_TYPE_PATH_NUMBER_ACL: 927 case TOMOYO_TYPE_PATH_NUMBER_ACL:
936 perm = container_of(ptr, struct tomoyo_path_number_acl, 928 perm = container_of(ptr, struct tomoyo_path_number_acl,
937 head)->perm; 929 head)->perm;
938 for (i = 0; i < TOMOYO_MAX_PATH_NUMBER_OPERATION; i++)
939 if (perm & (1 << i))
940 count++;
941 break; 930 break;
942 case TOMOYO_TYPE_MKDEV_ACL: 931 case TOMOYO_TYPE_MKDEV_ACL:
943 perm = container_of(ptr, struct tomoyo_mkdev_acl, 932 perm = container_of(ptr, struct tomoyo_mkdev_acl,
944 head)->perm; 933 head)->perm;
945 for (i = 0; i < TOMOYO_MAX_MKDEV_OPERATION; i++)
946 if (perm & (1 << i))
947 count++;
948 break; 934 break;
949 default: 935 default:
950 count++; 936 perm = 1;
951 } 937 }
938 for (i = 0; i < 16; i++)
939 if (perm & (1 << i))
940 count++;
952 } 941 }
953 if (count < tomoyo_profile(domain->profile)->learning-> 942 if (count < tomoyo_profile(domain->profile)->learning->
954 learning_max_entry) 943 learning_max_entry)