aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-06-26 10:15:31 -0400
committerJames Morris <jmorris@namei.org>2011-06-28 19:31:19 -0400
commit7c75964f432d14062d8eccfc916aa290f56b5aab (patch)
tree8aecdb96f9f079dd36735c3acccb79f3d10d6559 /security
parent1252cc3b232e582e887623dc5f70979418caaaa2 (diff)
TOMOYO: Cleanup part 1.
In order to synchronize with TOMOYO 1.8's syntax, (1) Remove special handling for allow_read/write permission. (2) Replace deny_rewrite/allow_rewrite permission with allow_append permission. (3) Remove file_pattern keyword. (4) Remove allow_read permission from exception policy. (5) Allow creating domains in enforcing mode without calling supervisor. (6) Add permission check for opening directory for reading. (7) Add permission check for stat() operation. (8) Make "cat < /sys/kernel/security/tomoyo/self_domain" behave as if "cat /sys/kernel/security/tomoyo/self_domain". Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
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)