aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-07-08 00:22:41 -0400
committerJames Morris <jmorris@namei.org>2011-07-10 21:05:32 -0400
commit8761afd49ebff8ae04c1a7888af090177441d07d (patch)
treef43b52e1b8467eeea465762d2f9d0b81a336faa0 /security
parent2066a36125fcbf5220990173b9d8e8bc49ad7538 (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.c72
-rw-r--r--security/tomoyo/common.c45
-rw-r--r--security/tomoyo/common.h91
-rw-r--r--security/tomoyo/condition.c249
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 */
19static 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 }
118no_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(). */
108enum 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. */
62enum tomoyo_mode_index { 118enum 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. */
292struct tomoyo_request_info { 348struct 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. */
453struct 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. */
463struct 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". */
392struct tomoyo_condition_element { 482struct tomoyo_condition_element {
393 /* Left hand operand. */ 483 /* Left hand operand. */
@@ -733,6 +823,7 @@ void tomoyo_check_profile(void);
733void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp); 823void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp);
734void tomoyo_del_condition(struct list_head *element); 824void tomoyo_del_condition(struct list_head *element);
735void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 825void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
826void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
736void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns); 827void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
737void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 828void 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 */
253void 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;