diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-07-08 00:22:41 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-07-10 21:05:32 -0400 |
commit | 8761afd49ebff8ae04c1a7888af090177441d07d (patch) | |
tree | f43b52e1b8467eeea465762d2f9d0b81a336faa0 /security | |
parent | 2066a36125fcbf5220990173b9d8e8bc49ad7538 (diff) |
TOMOYO: Allow using owner/group etc. of file objects as conditions.
This patch adds support for permission checks using file object's DAC
attributes (e.g. owner/group) when checking file's pathnames. Hooks for passing
file object's pointers are in the last patch of this pathset.
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/audit.c | 72 | ||||
-rw-r--r-- | security/tomoyo/common.c | 45 | ||||
-rw-r--r-- | security/tomoyo/common.h | 91 | ||||
-rw-r--r-- | security/tomoyo/condition.c | 249 |
4 files changed, 457 insertions, 0 deletions
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c index 9381d0e7f78f..4973edd40718 100644 --- a/security/tomoyo/audit.c +++ b/security/tomoyo/audit.c | |||
@@ -10,6 +10,35 @@ | |||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | 11 | ||
12 | /** | 12 | /** |
13 | * tomoyo_filetype - Get string representation of file type. | ||
14 | * | ||
15 | * @mode: Mode value for stat(). | ||
16 | * | ||
17 | * Returns file type string. | ||
18 | */ | ||
19 | static inline const char *tomoyo_filetype(const mode_t mode) | ||
20 | { | ||
21 | switch (mode & S_IFMT) { | ||
22 | case S_IFREG: | ||
23 | case 0: | ||
24 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE]; | ||
25 | case S_IFDIR: | ||
26 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY]; | ||
27 | case S_IFLNK: | ||
28 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK]; | ||
29 | case S_IFIFO: | ||
30 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO]; | ||
31 | case S_IFSOCK: | ||
32 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET]; | ||
33 | case S_IFBLK: | ||
34 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV]; | ||
35 | case S_IFCHR: | ||
36 | return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV]; | ||
37 | } | ||
38 | return "unknown"; /* This should not happen. */ | ||
39 | } | ||
40 | |||
41 | /** | ||
13 | * tomoyo_print_header - Get header line of audit log. | 42 | * tomoyo_print_header - Get header line of audit log. |
14 | * | 43 | * |
15 | * @r: Pointer to "struct tomoyo_request_info". | 44 | * @r: Pointer to "struct tomoyo_request_info". |
@@ -23,9 +52,11 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
23 | { | 52 | { |
24 | struct tomoyo_time stamp; | 53 | struct tomoyo_time stamp; |
25 | const pid_t gpid = task_pid_nr(current); | 54 | const pid_t gpid = task_pid_nr(current); |
55 | struct tomoyo_obj_info *obj = r->obj; | ||
26 | static const int tomoyo_buffer_len = 4096; | 56 | static const int tomoyo_buffer_len = 4096; |
27 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); | 57 | char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); |
28 | int pos; | 58 | int pos; |
59 | u8 i; | ||
29 | if (!buffer) | 60 | if (!buffer) |
30 | return NULL; | 61 | return NULL; |
31 | { | 62 | { |
@@ -44,6 +75,47 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
44 | current_uid(), current_gid(), current_euid(), | 75 | current_uid(), current_gid(), current_euid(), |
45 | current_egid(), current_suid(), current_sgid(), | 76 | current_egid(), current_suid(), current_sgid(), |
46 | current_fsuid(), current_fsgid()); | 77 | current_fsuid(), current_fsgid()); |
78 | if (!obj) | ||
79 | goto no_obj_info; | ||
80 | if (!obj->validate_done) { | ||
81 | tomoyo_get_attributes(obj); | ||
82 | obj->validate_done = true; | ||
83 | } | ||
84 | for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { | ||
85 | struct tomoyo_mini_stat *stat; | ||
86 | unsigned int dev; | ||
87 | mode_t mode; | ||
88 | if (!obj->stat_valid[i]) | ||
89 | continue; | ||
90 | stat = &obj->stat[i]; | ||
91 | dev = stat->dev; | ||
92 | mode = stat->mode; | ||
93 | if (i & 1) { | ||
94 | pos += snprintf(buffer + pos, | ||
95 | tomoyo_buffer_len - 1 - pos, | ||
96 | " path%u.parent={ uid=%u gid=%u " | ||
97 | "ino=%lu perm=0%o }", (i >> 1) + 1, | ||
98 | stat->uid, stat->gid, (unsigned long) | ||
99 | stat->ino, stat->mode & S_IALLUGO); | ||
100 | continue; | ||
101 | } | ||
102 | pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, | ||
103 | " path%u={ uid=%u gid=%u ino=%lu major=%u" | ||
104 | " minor=%u perm=0%o type=%s", (i >> 1) + 1, | ||
105 | stat->uid, stat->gid, (unsigned long) | ||
106 | stat->ino, MAJOR(dev), MINOR(dev), | ||
107 | mode & S_IALLUGO, tomoyo_filetype(mode)); | ||
108 | if (S_ISCHR(mode) || S_ISBLK(mode)) { | ||
109 | dev = stat->rdev; | ||
110 | pos += snprintf(buffer + pos, | ||
111 | tomoyo_buffer_len - 1 - pos, | ||
112 | " dev_major=%u dev_minor=%u", | ||
113 | MAJOR(dev), MINOR(dev)); | ||
114 | } | ||
115 | pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, | ||
116 | " }"); | ||
117 | } | ||
118 | no_obj_info: | ||
47 | if (pos < tomoyo_buffer_len - 1) | 119 | if (pos < tomoyo_buffer_len - 1) |
48 | return buffer; | 120 | return buffer; |
49 | kfree(buffer); | 121 | kfree(buffer); |
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 32ce1705b85a..ec02d2ab08c3 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -60,6 +60,51 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = { | |||
60 | [TOMOYO_TASK_FSGID] = "task.fsgid", | 60 | [TOMOYO_TASK_FSGID] = "task.fsgid", |
61 | [TOMOYO_TASK_PID] = "task.pid", | 61 | [TOMOYO_TASK_PID] = "task.pid", |
62 | [TOMOYO_TASK_PPID] = "task.ppid", | 62 | [TOMOYO_TASK_PPID] = "task.ppid", |
63 | [TOMOYO_TYPE_IS_SOCKET] = "socket", | ||
64 | [TOMOYO_TYPE_IS_SYMLINK] = "symlink", | ||
65 | [TOMOYO_TYPE_IS_FILE] = "file", | ||
66 | [TOMOYO_TYPE_IS_BLOCK_DEV] = "block", | ||
67 | [TOMOYO_TYPE_IS_DIRECTORY] = "directory", | ||
68 | [TOMOYO_TYPE_IS_CHAR_DEV] = "char", | ||
69 | [TOMOYO_TYPE_IS_FIFO] = "fifo", | ||
70 | [TOMOYO_MODE_SETUID] = "setuid", | ||
71 | [TOMOYO_MODE_SETGID] = "setgid", | ||
72 | [TOMOYO_MODE_STICKY] = "sticky", | ||
73 | [TOMOYO_MODE_OWNER_READ] = "owner_read", | ||
74 | [TOMOYO_MODE_OWNER_WRITE] = "owner_write", | ||
75 | [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute", | ||
76 | [TOMOYO_MODE_GROUP_READ] = "group_read", | ||
77 | [TOMOYO_MODE_GROUP_WRITE] = "group_write", | ||
78 | [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute", | ||
79 | [TOMOYO_MODE_OTHERS_READ] = "others_read", | ||
80 | [TOMOYO_MODE_OTHERS_WRITE] = "others_write", | ||
81 | [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", | ||
82 | [TOMOYO_PATH1_UID] = "path1.uid", | ||
83 | [TOMOYO_PATH1_GID] = "path1.gid", | ||
84 | [TOMOYO_PATH1_INO] = "path1.ino", | ||
85 | [TOMOYO_PATH1_MAJOR] = "path1.major", | ||
86 | [TOMOYO_PATH1_MINOR] = "path1.minor", | ||
87 | [TOMOYO_PATH1_PERM] = "path1.perm", | ||
88 | [TOMOYO_PATH1_TYPE] = "path1.type", | ||
89 | [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major", | ||
90 | [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor", | ||
91 | [TOMOYO_PATH2_UID] = "path2.uid", | ||
92 | [TOMOYO_PATH2_GID] = "path2.gid", | ||
93 | [TOMOYO_PATH2_INO] = "path2.ino", | ||
94 | [TOMOYO_PATH2_MAJOR] = "path2.major", | ||
95 | [TOMOYO_PATH2_MINOR] = "path2.minor", | ||
96 | [TOMOYO_PATH2_PERM] = "path2.perm", | ||
97 | [TOMOYO_PATH2_TYPE] = "path2.type", | ||
98 | [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major", | ||
99 | [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor", | ||
100 | [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid", | ||
101 | [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid", | ||
102 | [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino", | ||
103 | [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm", | ||
104 | [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid", | ||
105 | [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid", | ||
106 | [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino", | ||
107 | [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm", | ||
63 | }; | 108 | }; |
64 | 109 | ||
65 | /* String table for PREFERENCE keyword. */ | 110 | /* String table for PREFERENCE keyword. */ |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 958d433b0115..5a0fcedb332b 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -54,10 +54,66 @@ enum tomoyo_conditions_index { | |||
54 | TOMOYO_TASK_FSGID, /* current_fsgid() */ | 54 | TOMOYO_TASK_FSGID, /* current_fsgid() */ |
55 | TOMOYO_TASK_PID, /* sys_getpid() */ | 55 | TOMOYO_TASK_PID, /* sys_getpid() */ |
56 | TOMOYO_TASK_PPID, /* sys_getppid() */ | 56 | TOMOYO_TASK_PPID, /* sys_getppid() */ |
57 | TOMOYO_TYPE_IS_SOCKET, /* S_IFSOCK */ | ||
58 | TOMOYO_TYPE_IS_SYMLINK, /* S_IFLNK */ | ||
59 | TOMOYO_TYPE_IS_FILE, /* S_IFREG */ | ||
60 | TOMOYO_TYPE_IS_BLOCK_DEV, /* S_IFBLK */ | ||
61 | TOMOYO_TYPE_IS_DIRECTORY, /* S_IFDIR */ | ||
62 | TOMOYO_TYPE_IS_CHAR_DEV, /* S_IFCHR */ | ||
63 | TOMOYO_TYPE_IS_FIFO, /* S_IFIFO */ | ||
64 | TOMOYO_MODE_SETUID, /* S_ISUID */ | ||
65 | TOMOYO_MODE_SETGID, /* S_ISGID */ | ||
66 | TOMOYO_MODE_STICKY, /* S_ISVTX */ | ||
67 | TOMOYO_MODE_OWNER_READ, /* S_IRUSR */ | ||
68 | TOMOYO_MODE_OWNER_WRITE, /* S_IWUSR */ | ||
69 | TOMOYO_MODE_OWNER_EXECUTE, /* S_IXUSR */ | ||
70 | TOMOYO_MODE_GROUP_READ, /* S_IRGRP */ | ||
71 | TOMOYO_MODE_GROUP_WRITE, /* S_IWGRP */ | ||
72 | TOMOYO_MODE_GROUP_EXECUTE, /* S_IXGRP */ | ||
73 | TOMOYO_MODE_OTHERS_READ, /* S_IROTH */ | ||
74 | TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */ | ||
75 | TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */ | ||
76 | TOMOYO_PATH1_UID, | ||
77 | TOMOYO_PATH1_GID, | ||
78 | TOMOYO_PATH1_INO, | ||
79 | TOMOYO_PATH1_MAJOR, | ||
80 | TOMOYO_PATH1_MINOR, | ||
81 | TOMOYO_PATH1_PERM, | ||
82 | TOMOYO_PATH1_TYPE, | ||
83 | TOMOYO_PATH1_DEV_MAJOR, | ||
84 | TOMOYO_PATH1_DEV_MINOR, | ||
85 | TOMOYO_PATH2_UID, | ||
86 | TOMOYO_PATH2_GID, | ||
87 | TOMOYO_PATH2_INO, | ||
88 | TOMOYO_PATH2_MAJOR, | ||
89 | TOMOYO_PATH2_MINOR, | ||
90 | TOMOYO_PATH2_PERM, | ||
91 | TOMOYO_PATH2_TYPE, | ||
92 | TOMOYO_PATH2_DEV_MAJOR, | ||
93 | TOMOYO_PATH2_DEV_MINOR, | ||
94 | TOMOYO_PATH1_PARENT_UID, | ||
95 | TOMOYO_PATH1_PARENT_GID, | ||
96 | TOMOYO_PATH1_PARENT_INO, | ||
97 | TOMOYO_PATH1_PARENT_PERM, | ||
98 | TOMOYO_PATH2_PARENT_UID, | ||
99 | TOMOYO_PATH2_PARENT_GID, | ||
100 | TOMOYO_PATH2_PARENT_INO, | ||
101 | TOMOYO_PATH2_PARENT_PERM, | ||
57 | TOMOYO_MAX_CONDITION_KEYWORD, | 102 | TOMOYO_MAX_CONDITION_KEYWORD, |
58 | TOMOYO_NUMBER_UNION, | 103 | TOMOYO_NUMBER_UNION, |
59 | }; | 104 | }; |
60 | 105 | ||
106 | |||
107 | /* Index numbers for stat(). */ | ||
108 | enum tomoyo_path_stat_index { | ||
109 | /* Do not change this order. */ | ||
110 | TOMOYO_PATH1, | ||
111 | TOMOYO_PATH1_PARENT, | ||
112 | TOMOYO_PATH2, | ||
113 | TOMOYO_PATH2_PARENT, | ||
114 | TOMOYO_MAX_PATH_STAT | ||
115 | }; | ||
116 | |||
61 | /* Index numbers for operation mode. */ | 117 | /* Index numbers for operation mode. */ |
62 | enum tomoyo_mode_index { | 118 | enum tomoyo_mode_index { |
63 | TOMOYO_CONFIG_DISABLED, | 119 | TOMOYO_CONFIG_DISABLED, |
@@ -290,6 +346,11 @@ struct tomoyo_policy_namespace; | |||
290 | 346 | ||
291 | /* Structure for request info. */ | 347 | /* Structure for request info. */ |
292 | struct tomoyo_request_info { | 348 | struct tomoyo_request_info { |
349 | /* | ||
350 | * For holding parameters specific to operations which deal files. | ||
351 | * NULL if not dealing files. | ||
352 | */ | ||
353 | struct tomoyo_obj_info *obj; | ||
293 | struct tomoyo_domain_info *domain; | 354 | struct tomoyo_domain_info *domain; |
294 | /* For holding parameters. */ | 355 | /* For holding parameters. */ |
295 | union { | 356 | union { |
@@ -388,6 +449,35 @@ struct tomoyo_number_group { | |||
388 | struct tomoyo_number_union number; | 449 | struct tomoyo_number_union number; |
389 | }; | 450 | }; |
390 | 451 | ||
452 | /* Subset of "struct stat". Used by conditional ACL and audit logs. */ | ||
453 | struct tomoyo_mini_stat { | ||
454 | uid_t uid; | ||
455 | gid_t gid; | ||
456 | ino_t ino; | ||
457 | mode_t mode; | ||
458 | dev_t dev; | ||
459 | dev_t rdev; | ||
460 | }; | ||
461 | |||
462 | /* Structure for attribute checks in addition to pathname checks. */ | ||
463 | struct tomoyo_obj_info { | ||
464 | /* | ||
465 | * True if tomoyo_get_attributes() was already called, false otherwise. | ||
466 | */ | ||
467 | bool validate_done; | ||
468 | /* True if @stat[] is valid. */ | ||
469 | bool stat_valid[TOMOYO_MAX_PATH_STAT]; | ||
470 | /* First pathname. Initialized with { NULL, NULL } if no path. */ | ||
471 | struct path path1; | ||
472 | /* Second pathname. Initialized with { NULL, NULL } if no path. */ | ||
473 | struct path path2; | ||
474 | /* | ||
475 | * Information on @path1, @path1's parent directory, @path2, @path2's | ||
476 | * parent directory. | ||
477 | */ | ||
478 | struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT]; | ||
479 | }; | ||
480 | |||
391 | /* Structure for entries which follows "struct tomoyo_condition". */ | 481 | /* Structure for entries which follows "struct tomoyo_condition". */ |
392 | struct tomoyo_condition_element { | 482 | struct tomoyo_condition_element { |
393 | /* Left hand operand. */ | 483 | /* Left hand operand. */ |
@@ -733,6 +823,7 @@ void tomoyo_check_profile(void); | |||
733 | void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp); | 823 | void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp); |
734 | void tomoyo_del_condition(struct list_head *element); | 824 | void tomoyo_del_condition(struct list_head *element); |
735 | void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); | 825 | void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); |
826 | void tomoyo_get_attributes(struct tomoyo_obj_info *obj); | ||
736 | void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns); | 827 | void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns); |
737 | void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) | 828 | void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) |
738 | __printf(2, 3); | 829 | __printf(2, 3); |
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index 0692df3cddcc..ac7ebeb47d7d 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c | |||
@@ -244,6 +244,54 @@ out: | |||
244 | } | 244 | } |
245 | 245 | ||
246 | /** | 246 | /** |
247 | * tomoyo_get_attributes - Revalidate "struct inode". | ||
248 | * | ||
249 | * @obj: Pointer to "struct tomoyo_obj_info". | ||
250 | * | ||
251 | * Returns nothing. | ||
252 | */ | ||
253 | void tomoyo_get_attributes(struct tomoyo_obj_info *obj) | ||
254 | { | ||
255 | u8 i; | ||
256 | struct dentry *dentry = NULL; | ||
257 | |||
258 | for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { | ||
259 | struct inode *inode; | ||
260 | switch (i) { | ||
261 | case TOMOYO_PATH1: | ||
262 | dentry = obj->path1.dentry; | ||
263 | if (!dentry) | ||
264 | continue; | ||
265 | break; | ||
266 | case TOMOYO_PATH2: | ||
267 | dentry = obj->path2.dentry; | ||
268 | if (!dentry) | ||
269 | continue; | ||
270 | break; | ||
271 | default: | ||
272 | if (!dentry) | ||
273 | continue; | ||
274 | dentry = dget_parent(dentry); | ||
275 | break; | ||
276 | } | ||
277 | inode = dentry->d_inode; | ||
278 | if (inode) { | ||
279 | struct tomoyo_mini_stat *stat = &obj->stat[i]; | ||
280 | stat->uid = inode->i_uid; | ||
281 | stat->gid = inode->i_gid; | ||
282 | stat->ino = inode->i_ino; | ||
283 | stat->mode = inode->i_mode; | ||
284 | stat->dev = inode->i_sb->s_dev; | ||
285 | stat->rdev = inode->i_rdev; | ||
286 | obj->stat_valid[i] = true; | ||
287 | } | ||
288 | if (i & 1) /* i == TOMOYO_PATH1_PARENT || | ||
289 | i == TOMOYO_PATH2_PARENT */ | ||
290 | dput(dentry); | ||
291 | } | ||
292 | } | ||
293 | |||
294 | /** | ||
247 | * tomoyo_condition - Check condition part. | 295 | * tomoyo_condition - Check condition part. |
248 | * | 296 | * |
249 | * @r: Pointer to "struct tomoyo_request_info". | 297 | * @r: Pointer to "struct tomoyo_request_info". |
@@ -261,16 +309,19 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
261 | unsigned long max_v[2] = { 0, 0 }; | 309 | unsigned long max_v[2] = { 0, 0 }; |
262 | const struct tomoyo_condition_element *condp; | 310 | const struct tomoyo_condition_element *condp; |
263 | const struct tomoyo_number_union *numbers_p; | 311 | const struct tomoyo_number_union *numbers_p; |
312 | struct tomoyo_obj_info *obj; | ||
264 | u16 condc; | 313 | u16 condc; |
265 | if (!cond) | 314 | if (!cond) |
266 | return true; | 315 | return true; |
267 | condc = cond->condc; | 316 | condc = cond->condc; |
317 | obj = r->obj; | ||
268 | condp = (struct tomoyo_condition_element *) (cond + 1); | 318 | condp = (struct tomoyo_condition_element *) (cond + 1); |
269 | numbers_p = (const struct tomoyo_number_union *) (condp + condc); | 319 | numbers_p = (const struct tomoyo_number_union *) (condp + condc); |
270 | for (i = 0; i < condc; i++) { | 320 | for (i = 0; i < condc; i++) { |
271 | const bool match = condp->equals; | 321 | const bool match = condp->equals; |
272 | const u8 left = condp->left; | 322 | const u8 left = condp->left; |
273 | const u8 right = condp->right; | 323 | const u8 right = condp->right; |
324 | bool is_bitop[2] = { false, false }; | ||
274 | u8 j; | 325 | u8 j; |
275 | condp++; | 326 | condp++; |
276 | /* Check numeric or bit-op expressions. */ | 327 | /* Check numeric or bit-op expressions. */ |
@@ -308,14 +359,185 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
308 | case TOMOYO_TASK_PPID: | 359 | case TOMOYO_TASK_PPID: |
309 | value = tomoyo_sys_getppid(); | 360 | value = tomoyo_sys_getppid(); |
310 | break; | 361 | break; |
362 | case TOMOYO_TYPE_IS_SOCKET: | ||
363 | value = S_IFSOCK; | ||
364 | break; | ||
365 | case TOMOYO_TYPE_IS_SYMLINK: | ||
366 | value = S_IFLNK; | ||
367 | break; | ||
368 | case TOMOYO_TYPE_IS_FILE: | ||
369 | value = S_IFREG; | ||
370 | break; | ||
371 | case TOMOYO_TYPE_IS_BLOCK_DEV: | ||
372 | value = S_IFBLK; | ||
373 | break; | ||
374 | case TOMOYO_TYPE_IS_DIRECTORY: | ||
375 | value = S_IFDIR; | ||
376 | break; | ||
377 | case TOMOYO_TYPE_IS_CHAR_DEV: | ||
378 | value = S_IFCHR; | ||
379 | break; | ||
380 | case TOMOYO_TYPE_IS_FIFO: | ||
381 | value = S_IFIFO; | ||
382 | break; | ||
383 | case TOMOYO_MODE_SETUID: | ||
384 | value = S_ISUID; | ||
385 | break; | ||
386 | case TOMOYO_MODE_SETGID: | ||
387 | value = S_ISGID; | ||
388 | break; | ||
389 | case TOMOYO_MODE_STICKY: | ||
390 | value = S_ISVTX; | ||
391 | break; | ||
392 | case TOMOYO_MODE_OWNER_READ: | ||
393 | value = S_IRUSR; | ||
394 | break; | ||
395 | case TOMOYO_MODE_OWNER_WRITE: | ||
396 | value = S_IWUSR; | ||
397 | break; | ||
398 | case TOMOYO_MODE_OWNER_EXECUTE: | ||
399 | value = S_IXUSR; | ||
400 | break; | ||
401 | case TOMOYO_MODE_GROUP_READ: | ||
402 | value = S_IRGRP; | ||
403 | break; | ||
404 | case TOMOYO_MODE_GROUP_WRITE: | ||
405 | value = S_IWGRP; | ||
406 | break; | ||
407 | case TOMOYO_MODE_GROUP_EXECUTE: | ||
408 | value = S_IXGRP; | ||
409 | break; | ||
410 | case TOMOYO_MODE_OTHERS_READ: | ||
411 | value = S_IROTH; | ||
412 | break; | ||
413 | case TOMOYO_MODE_OTHERS_WRITE: | ||
414 | value = S_IWOTH; | ||
415 | break; | ||
416 | case TOMOYO_MODE_OTHERS_EXECUTE: | ||
417 | value = S_IXOTH; | ||
418 | break; | ||
311 | case TOMOYO_NUMBER_UNION: | 419 | case TOMOYO_NUMBER_UNION: |
312 | /* Fetch values later. */ | 420 | /* Fetch values later. */ |
313 | break; | 421 | break; |
314 | default: | 422 | default: |
423 | if (!obj) | ||
424 | goto out; | ||
425 | if (!obj->validate_done) { | ||
426 | tomoyo_get_attributes(obj); | ||
427 | obj->validate_done = true; | ||
428 | } | ||
429 | { | ||
430 | u8 stat_index; | ||
431 | struct tomoyo_mini_stat *stat; | ||
432 | switch (index) { | ||
433 | case TOMOYO_PATH1_UID: | ||
434 | case TOMOYO_PATH1_GID: | ||
435 | case TOMOYO_PATH1_INO: | ||
436 | case TOMOYO_PATH1_MAJOR: | ||
437 | case TOMOYO_PATH1_MINOR: | ||
438 | case TOMOYO_PATH1_TYPE: | ||
439 | case TOMOYO_PATH1_DEV_MAJOR: | ||
440 | case TOMOYO_PATH1_DEV_MINOR: | ||
441 | case TOMOYO_PATH1_PERM: | ||
442 | stat_index = TOMOYO_PATH1; | ||
443 | break; | ||
444 | case TOMOYO_PATH2_UID: | ||
445 | case TOMOYO_PATH2_GID: | ||
446 | case TOMOYO_PATH2_INO: | ||
447 | case TOMOYO_PATH2_MAJOR: | ||
448 | case TOMOYO_PATH2_MINOR: | ||
449 | case TOMOYO_PATH2_TYPE: | ||
450 | case TOMOYO_PATH2_DEV_MAJOR: | ||
451 | case TOMOYO_PATH2_DEV_MINOR: | ||
452 | case TOMOYO_PATH2_PERM: | ||
453 | stat_index = TOMOYO_PATH2; | ||
454 | break; | ||
455 | case TOMOYO_PATH1_PARENT_UID: | ||
456 | case TOMOYO_PATH1_PARENT_GID: | ||
457 | case TOMOYO_PATH1_PARENT_INO: | ||
458 | case TOMOYO_PATH1_PARENT_PERM: | ||
459 | stat_index = | ||
460 | TOMOYO_PATH1_PARENT; | ||
461 | break; | ||
462 | case TOMOYO_PATH2_PARENT_UID: | ||
463 | case TOMOYO_PATH2_PARENT_GID: | ||
464 | case TOMOYO_PATH2_PARENT_INO: | ||
465 | case TOMOYO_PATH2_PARENT_PERM: | ||
466 | stat_index = | ||
467 | TOMOYO_PATH2_PARENT; | ||
468 | break; | ||
469 | default: | ||
470 | goto out; | ||
471 | } | ||
472 | if (!obj->stat_valid[stat_index]) | ||
473 | goto out; | ||
474 | stat = &obj->stat[stat_index]; | ||
475 | switch (index) { | ||
476 | case TOMOYO_PATH1_UID: | ||
477 | case TOMOYO_PATH2_UID: | ||
478 | case TOMOYO_PATH1_PARENT_UID: | ||
479 | case TOMOYO_PATH2_PARENT_UID: | ||
480 | value = stat->uid; | ||
481 | break; | ||
482 | case TOMOYO_PATH1_GID: | ||
483 | case TOMOYO_PATH2_GID: | ||
484 | case TOMOYO_PATH1_PARENT_GID: | ||
485 | case TOMOYO_PATH2_PARENT_GID: | ||
486 | value = stat->gid; | ||
487 | break; | ||
488 | case TOMOYO_PATH1_INO: | ||
489 | case TOMOYO_PATH2_INO: | ||
490 | case TOMOYO_PATH1_PARENT_INO: | ||
491 | case TOMOYO_PATH2_PARENT_INO: | ||
492 | value = stat->ino; | ||
493 | break; | ||
494 | case TOMOYO_PATH1_MAJOR: | ||
495 | case TOMOYO_PATH2_MAJOR: | ||
496 | value = MAJOR(stat->dev); | ||
497 | break; | ||
498 | case TOMOYO_PATH1_MINOR: | ||
499 | case TOMOYO_PATH2_MINOR: | ||
500 | value = MINOR(stat->dev); | ||
501 | break; | ||
502 | case TOMOYO_PATH1_TYPE: | ||
503 | case TOMOYO_PATH2_TYPE: | ||
504 | value = stat->mode & S_IFMT; | ||
505 | break; | ||
506 | case TOMOYO_PATH1_DEV_MAJOR: | ||
507 | case TOMOYO_PATH2_DEV_MAJOR: | ||
508 | value = MAJOR(stat->rdev); | ||
509 | break; | ||
510 | case TOMOYO_PATH1_DEV_MINOR: | ||
511 | case TOMOYO_PATH2_DEV_MINOR: | ||
512 | value = MINOR(stat->rdev); | ||
513 | break; | ||
514 | case TOMOYO_PATH1_PERM: | ||
515 | case TOMOYO_PATH2_PERM: | ||
516 | case TOMOYO_PATH1_PARENT_PERM: | ||
517 | case TOMOYO_PATH2_PARENT_PERM: | ||
518 | value = stat->mode & S_IALLUGO; | ||
519 | break; | ||
520 | } | ||
521 | } | ||
315 | break; | 522 | break; |
316 | } | 523 | } |
317 | max_v[j] = value; | 524 | max_v[j] = value; |
318 | min_v[j] = value; | 525 | min_v[j] = value; |
526 | switch (index) { | ||
527 | case TOMOYO_MODE_SETUID: | ||
528 | case TOMOYO_MODE_SETGID: | ||
529 | case TOMOYO_MODE_STICKY: | ||
530 | case TOMOYO_MODE_OWNER_READ: | ||
531 | case TOMOYO_MODE_OWNER_WRITE: | ||
532 | case TOMOYO_MODE_OWNER_EXECUTE: | ||
533 | case TOMOYO_MODE_GROUP_READ: | ||
534 | case TOMOYO_MODE_GROUP_WRITE: | ||
535 | case TOMOYO_MODE_GROUP_EXECUTE: | ||
536 | case TOMOYO_MODE_OTHERS_READ: | ||
537 | case TOMOYO_MODE_OTHERS_WRITE: | ||
538 | case TOMOYO_MODE_OTHERS_EXECUTE: | ||
539 | is_bitop[j] = true; | ||
540 | } | ||
319 | } | 541 | } |
320 | if (left == TOMOYO_NUMBER_UNION) { | 542 | if (left == TOMOYO_NUMBER_UNION) { |
321 | /* Fetch values now. */ | 543 | /* Fetch values now. */ |
@@ -339,6 +561,33 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
339 | } | 561 | } |
340 | goto out; | 562 | goto out; |
341 | } | 563 | } |
564 | /* | ||
565 | * Bit operation is valid only when counterpart value | ||
566 | * represents permission. | ||
567 | */ | ||
568 | if (is_bitop[0] && is_bitop[1]) { | ||
569 | goto out; | ||
570 | } else if (is_bitop[0]) { | ||
571 | switch (right) { | ||
572 | case TOMOYO_PATH1_PERM: | ||
573 | case TOMOYO_PATH1_PARENT_PERM: | ||
574 | case TOMOYO_PATH2_PERM: | ||
575 | case TOMOYO_PATH2_PARENT_PERM: | ||
576 | if (!(max_v[0] & max_v[1]) == !match) | ||
577 | continue; | ||
578 | } | ||
579 | goto out; | ||
580 | } else if (is_bitop[1]) { | ||
581 | switch (left) { | ||
582 | case TOMOYO_PATH1_PERM: | ||
583 | case TOMOYO_PATH1_PARENT_PERM: | ||
584 | case TOMOYO_PATH2_PERM: | ||
585 | case TOMOYO_PATH2_PARENT_PERM: | ||
586 | if (!(max_v[0] & max_v[1]) == !match) | ||
587 | continue; | ||
588 | } | ||
589 | goto out; | ||
590 | } | ||
342 | /* Normal value range comparison. */ | 591 | /* Normal value range comparison. */ |
343 | if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match) | 592 | if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match) |
344 | continue; | 593 | continue; |