aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2011-07-08 00:23:44 -0400
committerJames Morris <jmorris@namei.org>2011-07-10 21:05:33 -0400
commit2ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563 (patch)
treeb9f6051059a2a90547a4501bf296b0cf3c9dbc76
parent8761afd49ebff8ae04c1a7888af090177441d07d (diff)
TOMOYO: Allow using executable's realpath and symlink's target as conditions.
This patch adds support for permission checks using executable file's realpath upon execve() and symlink's target upon symlink(). Hooks 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>
-rw-r--r--security/tomoyo/audit.c21
-rw-r--r--security/tomoyo/common.c66
-rw-r--r--security/tomoyo/common.h24
-rw-r--r--security/tomoyo/condition.c116
-rw-r--r--security/tomoyo/gc.c5
5 files changed, 228 insertions, 4 deletions
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index 4973edd4071..b33a20accbe 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -140,6 +140,8 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
140{ 140{
141 char *buf = NULL; 141 char *buf = NULL;
142 const char *header = NULL; 142 const char *header = NULL;
143 char *realpath = NULL;
144 const char *symlink = NULL;
143 int pos; 145 int pos;
144 const char *domainname = r->domain->domainname->name; 146 const char *domainname = r->domain->domainname->name;
145 header = tomoyo_print_header(r); 147 header = tomoyo_print_header(r);
@@ -147,15 +149,34 @@ char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
147 return NULL; 149 return NULL;
148 /* +10 is for '\n' etc. and '\0'. */ 150 /* +10 is for '\n' etc. and '\0'. */
149 len += strlen(domainname) + strlen(header) + 10; 151 len += strlen(domainname) + strlen(header) + 10;
152 if (r->ee) {
153 struct file *file = r->ee->bprm->file;
154 realpath = tomoyo_realpath_from_path(&file->f_path);
155 if (!realpath)
156 goto out;
157 /* +80 is for " exec={ realpath=\"%s\" }" */
158 len += strlen(realpath) + 80;
159 } else if (r->obj && r->obj->symlink_target) {
160 symlink = r->obj->symlink_target->name;
161 /* +18 is for " symlink.target=\"%s\"" */
162 len += 18 + strlen(symlink);
163 }
150 len = tomoyo_round2(len); 164 len = tomoyo_round2(len);
151 buf = kzalloc(len, GFP_NOFS); 165 buf = kzalloc(len, GFP_NOFS);
152 if (!buf) 166 if (!buf)
153 goto out; 167 goto out;
154 len--; 168 len--;
155 pos = snprintf(buf, len, "%s", header); 169 pos = snprintf(buf, len, "%s", header);
170 if (realpath) {
171 pos += snprintf(buf + pos, len - pos,
172 " exec={ realpath=\"%s\" }", realpath);
173 } else if (symlink)
174 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
175 symlink);
156 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); 176 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
157 vsnprintf(buf + pos, len - pos, fmt, args); 177 vsnprintf(buf + pos, len - pos, fmt, args);
158out: 178out:
179 kfree(realpath);
159 kfree(header); 180 kfree(header);
160 return buf; 181 return buf;
161} 182}
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ec02d2ab08c..69d6b59f593 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -79,6 +79,8 @@ const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
79 [TOMOYO_MODE_OTHERS_READ] = "others_read", 79 [TOMOYO_MODE_OTHERS_READ] = "others_read",
80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write", 80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", 81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
82 [TOMOYO_EXEC_REALPATH] = "exec.realpath",
83 [TOMOYO_SYMLINK_TARGET] = "symlink.target",
82 [TOMOYO_PATH1_UID] = "path1.uid", 84 [TOMOYO_PATH1_UID] = "path1.uid",
83 [TOMOYO_PATH1_GID] = "path1.gid", 85 [TOMOYO_PATH1_GID] = "path1.gid",
84 [TOMOYO_PATH1_INO] = "path1.ino", 86 [TOMOYO_PATH1_INO] = "path1.ino",
@@ -353,6 +355,27 @@ static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
353} 355}
354 356
355/** 357/**
358 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
359 *
360 * @head: Pointer to "struct tomoyo_io_buffer".
361 * @ptr: Pointer to "struct tomoyo_name_union".
362 *
363 * Returns nothing.
364 */
365static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
366 const struct tomoyo_name_union *ptr)
367{
368 if (ptr->group) {
369 tomoyo_set_string(head, "@");
370 tomoyo_set_string(head, ptr->group->group_name->name);
371 } else {
372 tomoyo_set_string(head, "\"");
373 tomoyo_set_string(head, ptr->filename->name);
374 tomoyo_set_string(head, "\"");
375 }
376}
377
378/**
356 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. 379 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
357 * 380 *
358 * @head: Pointer to "struct tomoyo_io_buffer". 381 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1101,6 +1124,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1101 (typeof(condp)) (cond + 1); 1124 (typeof(condp)) (cond + 1);
1102 const struct tomoyo_number_union *numbers_p = 1125 const struct tomoyo_number_union *numbers_p =
1103 (typeof(numbers_p)) (condp + condc); 1126 (typeof(numbers_p)) (condp + condc);
1127 const struct tomoyo_name_union *names_p =
1128 (typeof(names_p))
1129 (numbers_p + cond->numbers_count);
1104 u16 skip; 1130 u16 skip;
1105 for (skip = 0; skip < head->r.cond_index; skip++) { 1131 for (skip = 0; skip < head->r.cond_index; skip++) {
1106 const u8 left = condp->left; 1132 const u8 left = condp->left;
@@ -1112,6 +1138,9 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1112 break; 1138 break;
1113 } 1139 }
1114 switch (right) { 1140 switch (right) {
1141 case TOMOYO_NAME_UNION:
1142 names_p++;
1143 break;
1115 case TOMOYO_NUMBER_UNION: 1144 case TOMOYO_NUMBER_UNION:
1116 numbers_p++; 1145 numbers_p++;
1117 break; 1146 break;
@@ -1138,6 +1167,10 @@ static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1138 } 1167 }
1139 tomoyo_set_string(head, match ? "=" : "!="); 1168 tomoyo_set_string(head, match ? "=" : "!=");
1140 switch (right) { 1169 switch (right) {
1170 case TOMOYO_NAME_UNION:
1171 tomoyo_print_name_union_quoted
1172 (head, names_p++);
1173 break;
1141 case TOMOYO_NUMBER_UNION: 1174 case TOMOYO_NUMBER_UNION:
1142 tomoyo_print_number_union_nospace 1175 tomoyo_print_number_union_nospace
1143 (head, numbers_p++); 1176 (head, numbers_p++);
@@ -1666,6 +1699,22 @@ static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1666static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1699static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1667 1700
1668/** 1701/**
1702 * tomoyo_truncate - Truncate a line.
1703 *
1704 * @str: String to truncate.
1705 *
1706 * Returns length of truncated @str.
1707 */
1708static int tomoyo_truncate(char *str)
1709{
1710 char *start = str;
1711 while (*(unsigned char *) str > (unsigned char) ' ')
1712 str++;
1713 *str = '\0';
1714 return strlen(start) + 1;
1715}
1716
1717/**
1669 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. 1718 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1670 * 1719 *
1671 * @domain: Pointer to "struct tomoyo_domain_info". 1720 * @domain: Pointer to "struct tomoyo_domain_info".
@@ -1676,6 +1725,8 @@ static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1676static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) 1725static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1677{ 1726{
1678 char *buffer; 1727 char *buffer;
1728 char *realpath = NULL;
1729 char *symlink = NULL;
1679 char *cp = strchr(header, '\n'); 1730 char *cp = strchr(header, '\n');
1680 int len; 1731 int len;
1681 if (!cp) 1732 if (!cp)
@@ -1685,10 +1736,25 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1685 return; 1736 return;
1686 *cp++ = '\0'; 1737 *cp++ = '\0';
1687 len = strlen(cp) + 1; 1738 len = strlen(cp) + 1;
1739 /* strstr() will return NULL if ordering is wrong. */
1740 if (*cp == 'f') {
1741 realpath = strstr(header, " exec={ realpath=\"");
1742 if (realpath) {
1743 realpath += 8;
1744 len += tomoyo_truncate(realpath) + 6;
1745 }
1746 symlink = strstr(header, " symlink.target=\"");
1747 if (symlink)
1748 len += tomoyo_truncate(symlink + 1) + 1;
1749 }
1688 buffer = kmalloc(len, GFP_NOFS); 1750 buffer = kmalloc(len, GFP_NOFS);
1689 if (!buffer) 1751 if (!buffer)
1690 return; 1752 return;
1691 snprintf(buffer, len - 1, "%s", cp); 1753 snprintf(buffer, len - 1, "%s", cp);
1754 if (realpath)
1755 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
1756 if (symlink)
1757 tomoyo_addprintf(buffer, len, "%s", symlink);
1692 tomoyo_normalize_line(buffer); 1758 tomoyo_normalize_line(buffer);
1693 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, 1759 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1694 false)) 1760 false))
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 5a0fcedb332..7e56e6b364e 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -73,6 +73,8 @@ enum tomoyo_conditions_index {
73 TOMOYO_MODE_OTHERS_READ, /* S_IROTH */ 73 TOMOYO_MODE_OTHERS_READ, /* S_IROTH */
74 TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */ 74 TOMOYO_MODE_OTHERS_WRITE, /* S_IWOTH */
75 TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */ 75 TOMOYO_MODE_OTHERS_EXECUTE, /* S_IXOTH */
76 TOMOYO_EXEC_REALPATH,
77 TOMOYO_SYMLINK_TARGET,
76 TOMOYO_PATH1_UID, 78 TOMOYO_PATH1_UID,
77 TOMOYO_PATH1_GID, 79 TOMOYO_PATH1_GID,
78 TOMOYO_PATH1_INO, 80 TOMOYO_PATH1_INO,
@@ -101,6 +103,7 @@ enum tomoyo_conditions_index {
101 TOMOYO_PATH2_PARENT_PERM, 103 TOMOYO_PATH2_PARENT_PERM,
102 TOMOYO_MAX_CONDITION_KEYWORD, 104 TOMOYO_MAX_CONDITION_KEYWORD,
103 TOMOYO_NUMBER_UNION, 105 TOMOYO_NUMBER_UNION,
106 TOMOYO_NAME_UNION,
104}; 107};
105 108
106 109
@@ -351,6 +354,11 @@ struct tomoyo_request_info {
351 * NULL if not dealing files. 354 * NULL if not dealing files.
352 */ 355 */
353 struct tomoyo_obj_info *obj; 356 struct tomoyo_obj_info *obj;
357 /*
358 * For holding parameters specific to execve() request.
359 * NULL if not dealing do_execve().
360 */
361 struct tomoyo_execve *ee;
354 struct tomoyo_domain_info *domain; 362 struct tomoyo_domain_info *domain;
355 /* For holding parameters. */ 363 /* For holding parameters. */
356 union { 364 union {
@@ -476,6 +484,20 @@ struct tomoyo_obj_info {
476 * parent directory. 484 * parent directory.
477 */ 485 */
478 struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT]; 486 struct tomoyo_mini_stat stat[TOMOYO_MAX_PATH_STAT];
487 /*
488 * Content of symbolic link to be created. NULL for operations other
489 * than symlink().
490 */
491 struct tomoyo_path_info *symlink_target;
492};
493
494/* Structure for execve() operation. */
495struct tomoyo_execve {
496 struct tomoyo_request_info r;
497 struct tomoyo_obj_info obj;
498 struct linux_binprm *bprm;
499 /* For temporary use. */
500 char *tmp; /* Size is TOMOYO_EXEC_TMPSIZE bytes */
479}; 501};
480 502
481/* Structure for entries which follows "struct tomoyo_condition". */ 503/* Structure for entries which follows "struct tomoyo_condition". */
@@ -494,9 +516,11 @@ struct tomoyo_condition {
494 u32 size; /* Memory size allocated for this entry. */ 516 u32 size; /* Memory size allocated for this entry. */
495 u16 condc; /* Number of conditions in this struct. */ 517 u16 condc; /* Number of conditions in this struct. */
496 u16 numbers_count; /* Number of "struct tomoyo_number_union values". */ 518 u16 numbers_count; /* Number of "struct tomoyo_number_union values". */
519 u16 names_count; /* Number of "struct tomoyo_name_union names". */
497 /* 520 /*
498 * struct tomoyo_condition_element condition[condc]; 521 * struct tomoyo_condition_element condition[condc];
499 * struct tomoyo_number_union values[numbers_count]; 522 * struct tomoyo_number_union values[numbers_count];
523 * struct tomoyo_name_union names[names_count];
500 */ 524 */
501}; 525};
502 526
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index ac7ebeb47d7..790b9872cc3 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -11,6 +11,68 @@
11LIST_HEAD(tomoyo_condition_list); 11LIST_HEAD(tomoyo_condition_list);
12 12
13/** 13/**
14 * tomoyo_scan_exec_realpath - Check "exec.realpath" parameter of "struct tomoyo_condition".
15 *
16 * @file: Pointer to "struct file".
17 * @ptr: Pointer to "struct tomoyo_name_union".
18 * @match: True if "exec.realpath=", false if "exec.realpath!=".
19 *
20 * Returns true on success, false otherwise.
21 */
22static bool tomoyo_scan_exec_realpath(struct file *file,
23 const struct tomoyo_name_union *ptr,
24 const bool match)
25{
26 bool result;
27 struct tomoyo_path_info exe;
28 if (!file)
29 return false;
30 exe.name = tomoyo_realpath_from_path(&file->f_path);
31 if (!exe.name)
32 return false;
33 tomoyo_fill_path_info(&exe);
34 result = tomoyo_compare_name_union(&exe, ptr);
35 kfree(exe.name);
36 return result == match;
37}
38
39/**
40 * tomoyo_get_dqword - tomoyo_get_name() for a quoted string.
41 *
42 * @start: String to save.
43 *
44 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
45 */
46static const struct tomoyo_path_info *tomoyo_get_dqword(char *start)
47{
48 char *cp = start + strlen(start) - 1;
49 if (cp == start || *start++ != '"' || *cp != '"')
50 return NULL;
51 *cp = '\0';
52 if (*start && !tomoyo_correct_word(start))
53 return NULL;
54 return tomoyo_get_name(start);
55}
56
57/**
58 * tomoyo_parse_name_union_quoted - Parse a quoted word.
59 *
60 * @param: Pointer to "struct tomoyo_acl_param".
61 * @ptr: Pointer to "struct tomoyo_name_union".
62 *
63 * Returns true on success, false otherwise.
64 */
65static bool tomoyo_parse_name_union_quoted(struct tomoyo_acl_param *param,
66 struct tomoyo_name_union *ptr)
67{
68 char *filename = param->data;
69 if (*filename == '@')
70 return tomoyo_parse_name_union(param, ptr);
71 ptr->filename = tomoyo_get_dqword(filename);
72 return ptr->filename != NULL;
73}
74
75/**
14 * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry. 76 * tomoyo_same_condition - Check for duplicated "struct tomoyo_condition" entry.
15 * 77 *
16 * @a: Pointer to "struct tomoyo_condition". 78 * @a: Pointer to "struct tomoyo_condition".
@@ -23,6 +85,7 @@ static inline bool tomoyo_same_condition(const struct tomoyo_condition *a,
23{ 85{
24 return a->size == b->size && a->condc == b->condc && 86 return a->size == b->size && a->condc == b->condc &&
25 a->numbers_count == b->numbers_count && 87 a->numbers_count == b->numbers_count &&
88 a->names_count == b->names_count &&
26 !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 89 !memcmp(a + 1, b + 1, a->size - sizeof(*a));
27} 90}
28 91
@@ -114,6 +177,7 @@ struct tomoyo_condition *tomoyo_get_condition(struct tomoyo_acl_param *param)
114 struct tomoyo_condition *entry = NULL; 177 struct tomoyo_condition *entry = NULL;
115 struct tomoyo_condition_element *condp = NULL; 178 struct tomoyo_condition_element *condp = NULL;
116 struct tomoyo_number_union *numbers_p = NULL; 179 struct tomoyo_number_union *numbers_p = NULL;
180 struct tomoyo_name_union *names_p = NULL;
117 struct tomoyo_condition e = { }; 181 struct tomoyo_condition e = { };
118 char * const start_of_string = param->data; 182 char * const start_of_string = param->data;
119 char * const end_of_string = start_of_string + strlen(start_of_string); 183 char * const end_of_string = start_of_string + strlen(start_of_string);
@@ -178,6 +242,20 @@ rerun:
178 e.condc++; 242 e.condc++;
179 else 243 else
180 e.condc--; 244 e.condc--;
245 if (left == TOMOYO_EXEC_REALPATH ||
246 left == TOMOYO_SYMLINK_TARGET) {
247 if (!names_p) {
248 e.names_count++;
249 } else {
250 e.names_count--;
251 right = TOMOYO_NAME_UNION;
252 param->data = right_word;
253 if (!tomoyo_parse_name_union_quoted(param,
254 names_p++))
255 goto out;
256 }
257 goto store_value;
258 }
181 right = tomoyo_condition_type(right_word); 259 right = tomoyo_condition_type(right_word);
182 if (right == TOMOYO_MAX_CONDITION_KEYWORD) { 260 if (right == TOMOYO_MAX_CONDITION_KEYWORD) {
183 if (!numbers_p) { 261 if (!numbers_p) {
@@ -191,6 +269,7 @@ rerun:
191 goto out; 269 goto out;
192 } 270 }
193 } 271 }
272store_value:
194 if (!condp) { 273 if (!condp) {
195 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " 274 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
196 "match=%u\n", __LINE__, left, right, !is_not); 275 "match=%u\n", __LINE__, left, right, !is_not);
@@ -204,21 +283,23 @@ rerun:
204 condp->equals); 283 condp->equals);
205 condp++; 284 condp++;
206 } 285 }
207 dprintk(KERN_INFO "%u: cond=%u numbers=%u\n", 286 dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u\n",
208 __LINE__, e.condc, e.numbers_count); 287 __LINE__, e.condc, e.numbers_count, e.names_count);
209 if (entry) { 288 if (entry) {
210 BUG_ON(e.numbers_count | e.condc); 289 BUG_ON(e.names_count | e.numbers_count | e.condc);
211 return tomoyo_commit_condition(entry); 290 return tomoyo_commit_condition(entry);
212 } 291 }
213 e.size = sizeof(*entry) 292 e.size = sizeof(*entry)
214 + e.condc * sizeof(struct tomoyo_condition_element) 293 + e.condc * sizeof(struct tomoyo_condition_element)
215 + e.numbers_count * sizeof(struct tomoyo_number_union); 294 + e.numbers_count * sizeof(struct tomoyo_number_union)
295 + e.names_count * sizeof(struct tomoyo_name_union);
216 entry = kzalloc(e.size, GFP_NOFS); 296 entry = kzalloc(e.size, GFP_NOFS);
217 if (!entry) 297 if (!entry)
218 return NULL; 298 return NULL;
219 *entry = e; 299 *entry = e;
220 condp = (struct tomoyo_condition_element *) (entry + 1); 300 condp = (struct tomoyo_condition_element *) (entry + 1);
221 numbers_p = (struct tomoyo_number_union *) (condp + e.condc); 301 numbers_p = (struct tomoyo_number_union *) (condp + e.condc);
302 names_p = (struct tomoyo_name_union *) (numbers_p + e.numbers_count);
222 { 303 {
223 bool flag = false; 304 bool flag = false;
224 for (pos = start_of_string; pos < end_of_string; pos++) { 305 for (pos = start_of_string; pos < end_of_string; pos++) {
@@ -309,6 +390,7 @@ bool tomoyo_condition(struct tomoyo_request_info *r,
309 unsigned long max_v[2] = { 0, 0 }; 390 unsigned long max_v[2] = { 0, 0 };
310 const struct tomoyo_condition_element *condp; 391 const struct tomoyo_condition_element *condp;
311 const struct tomoyo_number_union *numbers_p; 392 const struct tomoyo_number_union *numbers_p;
393 const struct tomoyo_name_union *names_p;
312 struct tomoyo_obj_info *obj; 394 struct tomoyo_obj_info *obj;
313 u16 condc; 395 u16 condc;
314 if (!cond) 396 if (!cond)
@@ -317,6 +399,8 @@ bool tomoyo_condition(struct tomoyo_request_info *r,
317 obj = r->obj; 399 obj = r->obj;
318 condp = (struct tomoyo_condition_element *) (cond + 1); 400 condp = (struct tomoyo_condition_element *) (cond + 1);
319 numbers_p = (const struct tomoyo_number_union *) (condp + condc); 401 numbers_p = (const struct tomoyo_number_union *) (condp + condc);
402 names_p = (const struct tomoyo_name_union *)
403 (numbers_p + cond->numbers_count);
320 for (i = 0; i < condc; i++) { 404 for (i = 0; i < condc; i++) {
321 const bool match = condp->equals; 405 const bool match = condp->equals;
322 const u8 left = condp->left; 406 const u8 left = condp->left;
@@ -324,6 +408,30 @@ bool tomoyo_condition(struct tomoyo_request_info *r,
324 bool is_bitop[2] = { false, false }; 408 bool is_bitop[2] = { false, false };
325 u8 j; 409 u8 j;
326 condp++; 410 condp++;
411 /* Check string expressions. */
412 if (right == TOMOYO_NAME_UNION) {
413 const struct tomoyo_name_union *ptr = names_p++;
414 switch (left) {
415 struct tomoyo_path_info *symlink;
416 struct tomoyo_execve *ee;
417 struct file *file;
418 case TOMOYO_SYMLINK_TARGET:
419 symlink = obj ? obj->symlink_target : NULL;
420 if (!symlink ||
421 !tomoyo_compare_name_union(symlink, ptr)
422 == match)
423 goto out;
424 break;
425 case TOMOYO_EXEC_REALPATH:
426 ee = r->ee;
427 file = ee ? ee->bprm->file : NULL;
428 if (!tomoyo_scan_exec_realpath(file, ptr,
429 match))
430 goto out;
431 break;
432 }
433 continue;
434 }
327 /* Check numeric or bit-op expressions. */ 435 /* Check numeric or bit-op expressions. */
328 for (j = 0; j < 2; j++) { 436 for (j = 0; j < 2; j++) {
329 const u8 index = j ? right : left; 437 const u8 index = j ? right : left;
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 21fccd67c25..e0502b6d586 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -357,13 +357,18 @@ void tomoyo_del_condition(struct list_head *element)
357 head.list); 357 head.list);
358 const u16 condc = cond->condc; 358 const u16 condc = cond->condc;
359 const u16 numbers_count = cond->numbers_count; 359 const u16 numbers_count = cond->numbers_count;
360 const u16 names_count = cond->names_count;
360 unsigned int i; 361 unsigned int i;
361 const struct tomoyo_condition_element *condp 362 const struct tomoyo_condition_element *condp
362 = (const struct tomoyo_condition_element *) (cond + 1); 363 = (const struct tomoyo_condition_element *) (cond + 1);
363 struct tomoyo_number_union *numbers_p 364 struct tomoyo_number_union *numbers_p
364 = (struct tomoyo_number_union *) (condp + condc); 365 = (struct tomoyo_number_union *) (condp + condc);
366 struct tomoyo_name_union *names_p
367 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
365 for (i = 0; i < numbers_count; i++) 368 for (i = 0; i < numbers_count; i++)
366 tomoyo_put_number_union(numbers_p++); 369 tomoyo_put_number_union(numbers_p++);
370 for (i = 0; i < names_count; i++)
371 tomoyo_put_name_union(names_p++);
367} 372}
368 373
369/** 374/**