aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-03 07:37:26 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:33:42 -0400
commit3f629636320dfa65804779a3fc333f3147f3b064 (patch)
treee44dc9f63ae8c6cd37d5471d014cd9b0449027e7 /security/tomoyo
parentc8c57e842720d8cc92ac8607f2d1c16d92314573 (diff)
TOMOYO: Allow wildcard for execute permission.
Some applications create and execute programs dynamically. We need to accept wildcard for execute permission because such programs contain random suffix in their filenames. This patch loosens up regulation of string parameters. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo')
-rw-r--r--security/tomoyo/common.c2
-rw-r--r--security/tomoyo/common.h7
-rw-r--r--security/tomoyo/domain.c21
-rw-r--r--security/tomoyo/file.c37
-rw-r--r--security/tomoyo/number_group.c3
-rw-r--r--security/tomoyo/path_group.c17
-rw-r--r--security/tomoyo/util.c154
7 files changed, 90 insertions, 151 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 98e3639db990..3f94011c6411 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -407,7 +407,7 @@ static int tomoyo_update_manager_entry(const char *manager,
407 return -EINVAL; 407 return -EINVAL;
408 e.is_domain = true; 408 e.is_domain = true;
409 } else { 409 } else {
410 if (!tomoyo_is_correct_path(manager, 1, -1, -1)) 410 if (!tomoyo_is_correct_path(manager))
411 return -EINVAL; 411 return -EINVAL;
412 } 412 }
413 e.manager = tomoyo_get_name(manager); 413 e.manager = tomoyo_get_name(manager);
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index f4a8aa244af5..d1b8d791bfff 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -672,16 +672,15 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
672/* Check whether the domainname is correct. */ 672/* Check whether the domainname is correct. */
673bool tomoyo_is_correct_domain(const unsigned char *domainname); 673bool tomoyo_is_correct_domain(const unsigned char *domainname);
674/* Check whether the token is correct. */ 674/* Check whether the token is correct. */
675bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 675bool tomoyo_is_correct_path(const char *filename);
676 const s8 pattern_type, const s8 end_type); 676bool tomoyo_is_correct_word(const char *string);
677/* Check whether the token can be a domainname. */ 677/* Check whether the token can be a domainname. */
678bool tomoyo_is_domain_def(const unsigned char *buffer); 678bool tomoyo_is_domain_def(const unsigned char *buffer);
679bool tomoyo_parse_name_union(const char *filename, 679bool tomoyo_parse_name_union(const char *filename,
680 struct tomoyo_name_union *ptr); 680 struct tomoyo_name_union *ptr);
681/* Check whether the given filename matches the given path_group. */ 681/* Check whether the given filename matches the given path_group. */
682bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 682bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
683 const struct tomoyo_path_group *group, 683 const struct tomoyo_path_group *group);
684 const bool may_use_pattern);
685/* Check whether the given value matches the given number_group. */ 684/* Check whether the given value matches the given number_group. */
686bool tomoyo_number_matches_group(const unsigned long min, 685bool tomoyo_number_matches_group(const unsigned long min,
687 const unsigned long max, 686 const unsigned long max,
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 7b8693e29a13..50f6e7972174 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -131,11 +131,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
131 struct tomoyo_domain_initializer_entry e = { .is_not = is_not }; 131 struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
132 int error = is_delete ? -ENOENT : -ENOMEM; 132 int error = is_delete ? -ENOENT : -ENOMEM;
133 133
134 if (!tomoyo_is_correct_path(program, 1, -1, -1)) 134 if (!tomoyo_is_correct_path(program))
135 return -EINVAL; /* No patterns allowed. */ 135 return -EINVAL;
136 if (domainname) { 136 if (domainname) {
137 if (!tomoyo_is_domain_def(domainname) && 137 if (!tomoyo_is_domain_def(domainname) &&
138 tomoyo_is_correct_path(domainname, 1, -1, -1)) 138 tomoyo_is_correct_path(domainname))
139 e.is_last_name = true; 139 e.is_last_name = true;
140 else if (!tomoyo_is_correct_domain(domainname)) 140 else if (!tomoyo_is_correct_domain(domainname))
141 return -EINVAL; 141 return -EINVAL;
@@ -342,12 +342,12 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
342 int error = is_delete ? -ENOENT : -ENOMEM; 342 int error = is_delete ? -ENOENT : -ENOMEM;
343 343
344 if (!tomoyo_is_domain_def(domainname) && 344 if (!tomoyo_is_domain_def(domainname) &&
345 tomoyo_is_correct_path(domainname, 1, -1, -1)) 345 tomoyo_is_correct_path(domainname))
346 e.is_last_name = true; 346 e.is_last_name = true;
347 else if (!tomoyo_is_correct_domain(domainname)) 347 else if (!tomoyo_is_correct_domain(domainname))
348 return -EINVAL; 348 return -EINVAL;
349 if (program) { 349 if (program) {
350 if (!tomoyo_is_correct_path(program, 1, -1, -1)) 350 if (!tomoyo_is_correct_path(program))
351 return -EINVAL; 351 return -EINVAL;
352 e.program = tomoyo_get_name(program); 352 e.program = tomoyo_get_name(program);
353 if (!e.program) 353 if (!e.program)
@@ -533,13 +533,14 @@ static int tomoyo_update_alias_entry(const char *original_name,
533 struct tomoyo_alias_entry e = { }; 533 struct tomoyo_alias_entry e = { };
534 int error = is_delete ? -ENOENT : -ENOMEM; 534 int error = is_delete ? -ENOENT : -ENOMEM;
535 535
536 if (!tomoyo_is_correct_path(original_name, 1, -1, -1) || 536 if (!tomoyo_is_correct_path(original_name) ||
537 !tomoyo_is_correct_path(aliased_name, 1, -1, -1)) 537 !tomoyo_is_correct_path(aliased_name))
538 return -EINVAL; /* No patterns allowed. */ 538 return -EINVAL;
539 e.original_name = tomoyo_get_name(original_name); 539 e.original_name = tomoyo_get_name(original_name);
540 e.aliased_name = tomoyo_get_name(aliased_name); 540 e.aliased_name = tomoyo_get_name(aliased_name);
541 if (!e.original_name || !e.aliased_name) 541 if (!e.original_name || !e.aliased_name ||
542 goto out; 542 e.original_name->is_patterned || e.aliased_name->is_patterned)
543 goto out; /* No patterns allowed. */
543 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 544 if (mutex_lock_interruptible(&tomoyo_policy_lock))
544 goto out; 545 goto out;
545 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) { 546 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index cef685415df1..83fa17a1113a 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -65,23 +65,10 @@ bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
65 const struct tomoyo_name_union *ptr) 65 const struct tomoyo_name_union *ptr)
66{ 66{
67 if (ptr->is_group) 67 if (ptr->is_group)
68 return tomoyo_path_matches_group(name, ptr->group, 1); 68 return tomoyo_path_matches_group(name, ptr->group);
69 return tomoyo_path_matches_pattern(name, ptr->filename); 69 return tomoyo_path_matches_pattern(name, ptr->filename);
70} 70}
71 71
72static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info
73 *name,
74 const struct tomoyo_name_union
75 *ptr, const bool may_use_pattern)
76{
77 if (ptr->is_group)
78 return tomoyo_path_matches_group(name, ptr->group,
79 may_use_pattern);
80 if (may_use_pattern || !ptr->filename->is_patterned)
81 return tomoyo_path_matches_pattern(name, ptr->filename);
82 return false;
83}
84
85void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 72void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
86{ 73{
87 if (ptr && ptr->is_group) 74 if (ptr && ptr->is_group)
@@ -247,7 +234,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
247 struct tomoyo_globally_readable_file_entry e = { }; 234 struct tomoyo_globally_readable_file_entry e = { };
248 int error = is_delete ? -ENOENT : -ENOMEM; 235 int error = is_delete ? -ENOENT : -ENOMEM;
249 236
250 if (!tomoyo_is_correct_path(filename, 1, 0, -1)) 237 if (!tomoyo_is_correct_word(filename))
251 return -EINVAL; 238 return -EINVAL;
252 e.filename = tomoyo_get_name(filename); 239 e.filename = tomoyo_get_name(filename);
253 if (!e.filename) 240 if (!e.filename)
@@ -391,13 +378,14 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
391 const bool is_delete) 378 const bool is_delete)
392{ 379{
393 struct tomoyo_pattern_entry *ptr; 380 struct tomoyo_pattern_entry *ptr;
394 struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) }; 381 struct tomoyo_pattern_entry e = { };
395 int error = is_delete ? -ENOENT : -ENOMEM; 382 int error = is_delete ? -ENOENT : -ENOMEM;
396 383
384 if (!tomoyo_is_correct_word(pattern))
385 return -EINVAL;
386 e.pattern = tomoyo_get_name(pattern);
397 if (!e.pattern) 387 if (!e.pattern)
398 return error; 388 return error;
399 if (!e.pattern->is_patterned)
400 goto out;
401 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 389 if (mutex_lock_interruptible(&tomoyo_policy_lock))
402 goto out; 390 goto out;
403 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { 391 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
@@ -543,7 +531,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
543 struct tomoyo_no_rewrite_entry e = { }; 531 struct tomoyo_no_rewrite_entry e = { };
544 int error = is_delete ? -ENOENT : -ENOMEM; 532 int error = is_delete ? -ENOENT : -ENOMEM;
545 533
546 if (!tomoyo_is_correct_path(pattern, 0, 0, 0)) 534 if (!tomoyo_is_correct_word(pattern))
547 return -EINVAL; 535 return -EINVAL;
548 e.pattern = tomoyo_get_name(pattern); 536 e.pattern = tomoyo_get_name(pattern);
549 if (!e.pattern) 537 if (!e.pattern)
@@ -690,7 +678,6 @@ static int tomoyo_update_file_acl(u8 perm, const char *filename,
690 * @r: Pointer to "struct tomoyo_request_info". 678 * @r: Pointer to "struct tomoyo_request_info".
691 * @filename: Filename to check. 679 * @filename: Filename to check.
692 * @perm: Permission. 680 * @perm: Permission.
693 * @may_use_pattern: True if patterned ACL is permitted.
694 * 681 *
695 * Returns 0 on success, -EPERM otherwise. 682 * Returns 0 on success, -EPERM otherwise.
696 * 683 *
@@ -698,7 +685,7 @@ static int tomoyo_update_file_acl(u8 perm, const char *filename,
698 */ 685 */
699static int tomoyo_path_acl(const struct tomoyo_request_info *r, 686static int tomoyo_path_acl(const struct tomoyo_request_info *r,
700 const struct tomoyo_path_info *filename, 687 const struct tomoyo_path_info *filename,
701 const u32 perm, const bool may_use_pattern) 688 const u32 perm)
702{ 689{
703 struct tomoyo_domain_info *domain = r->domain; 690 struct tomoyo_domain_info *domain = r->domain;
704 struct tomoyo_acl_info *ptr; 691 struct tomoyo_acl_info *ptr;
@@ -710,8 +697,7 @@ static int tomoyo_path_acl(const struct tomoyo_request_info *r,
710 continue; 697 continue;
711 acl = container_of(ptr, struct tomoyo_path_acl, head); 698 acl = container_of(ptr, struct tomoyo_path_acl, head);
712 if (!(acl->perm & perm) || 699 if (!(acl->perm & perm) ||
713 !tomoyo_compare_name_union_pattern(filename, &acl->name, 700 !tomoyo_compare_name_union(filename, &acl->name))
714 may_use_pattern))
715 continue; 701 continue;
716 error = 0; 702 error = 0;
717 break; 703 break;
@@ -756,7 +742,7 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
756 } else 742 } else
757 BUG(); 743 BUG();
758 do { 744 do {
759 error = tomoyo_path_acl(r, filename, perm, mode != 1); 745 error = tomoyo_path_acl(r, filename, perm);
760 if (error && mode == 4 && !r->domain->ignore_global_allow_read 746 if (error && mode == 4 && !r->domain->ignore_global_allow_read
761 && tomoyo_is_globally_readable_file(filename)) 747 && tomoyo_is_globally_readable_file(filename))
762 error = 0; 748 error = 0;
@@ -764,7 +750,6 @@ static int tomoyo_file_perm(struct tomoyo_request_info *r,
764 break; 750 break;
765 tomoyo_warn_log(r, "%s %s", msg, filename->name); 751 tomoyo_warn_log(r, "%s %s", msg, filename->name);
766 error = tomoyo_supervisor(r, "allow_%s %s\n", msg, 752 error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
767 mode == 1 ? filename->name :
768 tomoyo_file_pattern(filename)); 753 tomoyo_file_pattern(filename));
769 /* 754 /*
770 * Do not retry for execute request, for alias may have 755 * Do not retry for execute request, for alias may have
@@ -1073,7 +1058,7 @@ static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
1073 1058
1074 next: 1059 next:
1075 do { 1060 do {
1076 error = tomoyo_path_acl(r, filename, 1 << operation, 1); 1061 error = tomoyo_path_acl(r, filename, 1 << operation);
1077 if (!error) 1062 if (!error)
1078 break; 1063 break;
1079 msg = tomoyo_path2keyword(operation); 1064 msg = tomoyo_path2keyword(operation);
diff --git a/security/tomoyo/number_group.c b/security/tomoyo/number_group.c
index c49792e09e81..8d6ef8f006ff 100644
--- a/security/tomoyo/number_group.c
+++ b/security/tomoyo/number_group.c
@@ -24,8 +24,7 @@ struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name)
24 struct tomoyo_number_group *group = NULL; 24 struct tomoyo_number_group *group = NULL;
25 const struct tomoyo_path_info *saved_group_name; 25 const struct tomoyo_path_info *saved_group_name;
26 int error = -ENOMEM; 26 int error = -ENOMEM;
27 if (!tomoyo_is_correct_path(group_name, 0, 0, 0) || 27 if (!tomoyo_is_correct_word(group_name))
28 !group_name[0])
29 return NULL; 28 return NULL;
30 saved_group_name = tomoyo_get_name(group_name); 29 saved_group_name = tomoyo_get_name(group_name);
31 if (!saved_group_name) 30 if (!saved_group_name)
diff --git a/security/tomoyo/path_group.c b/security/tomoyo/path_group.c
index 636025e26b06..07e4f782367b 100644
--- a/security/tomoyo/path_group.c
+++ b/security/tomoyo/path_group.c
@@ -22,8 +22,7 @@ struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name)
22 struct tomoyo_path_group *group = NULL; 22 struct tomoyo_path_group *group = NULL;
23 const struct tomoyo_path_info *saved_group_name; 23 const struct tomoyo_path_info *saved_group_name;
24 int error = -ENOMEM; 24 int error = -ENOMEM;
25 if (!tomoyo_is_correct_path(group_name, 0, 0, 0) || 25 if (!tomoyo_is_correct_word(group_name))
26 !group_name[0])
27 return NULL; 26 return NULL;
28 saved_group_name = tomoyo_get_name(group_name); 27 saved_group_name = tomoyo_get_name(group_name);
29 if (!saved_group_name) 28 if (!saved_group_name)
@@ -141,29 +140,21 @@ bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head)
141 * 140 *
142 * @pathname: The name of pathname. 141 * @pathname: The name of pathname.
143 * @group: Pointer to "struct tomoyo_path_group". 142 * @group: Pointer to "struct tomoyo_path_group".
144 * @may_use_pattern: True if wild card is permitted.
145 * 143 *
146 * Returns true if @pathname matches pathnames in @group, false otherwise. 144 * Returns true if @pathname matches pathnames in @group, false otherwise.
147 * 145 *
148 * Caller holds tomoyo_read_lock(). 146 * Caller holds tomoyo_read_lock().
149 */ 147 */
150bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 148bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
151 const struct tomoyo_path_group *group, 149 const struct tomoyo_path_group *group)
152 const bool may_use_pattern)
153{ 150{
154 struct tomoyo_path_group_member *member; 151 struct tomoyo_path_group_member *member;
155 bool matched = false; 152 bool matched = false;
156 list_for_each_entry_rcu(member, &group->member_list, list) { 153 list_for_each_entry_rcu(member, &group->member_list, list) {
157 if (member->is_deleted) 154 if (member->is_deleted)
158 continue; 155 continue;
159 if (!member->member_name->is_patterned) { 156 if (!tomoyo_path_matches_pattern(pathname,
160 if (tomoyo_pathcmp(pathname, member->member_name)) 157 member->member_name))
161 continue;
162 } else if (may_use_pattern) {
163 if (!tomoyo_path_matches_pattern(pathname,
164 member->member_name))
165 continue;
166 } else
167 continue; 158 continue;
168 matched = true; 159 matched = true;
169 break; 160 break;
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 7b023f5e1314..592b76a2bce8 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -89,7 +89,7 @@ void tomoyo_print_ulong(char *buffer, const int buffer_len,
89bool tomoyo_parse_name_union(const char *filename, 89bool tomoyo_parse_name_union(const char *filename,
90 struct tomoyo_name_union *ptr) 90 struct tomoyo_name_union *ptr)
91{ 91{
92 if (!tomoyo_is_correct_path(filename, 0, 0, 0)) 92 if (!tomoyo_is_correct_word(filename))
93 return false; 93 return false;
94 if (filename[0] == '@') { 94 if (filename[0] == '@') {
95 ptr->group = tomoyo_get_path_group(filename + 1); 95 ptr->group = tomoyo_get_path_group(filename + 1);
@@ -115,7 +115,7 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num)
115 unsigned long v; 115 unsigned long v;
116 memset(num, 0, sizeof(*num)); 116 memset(num, 0, sizeof(*num));
117 if (data[0] == '@') { 117 if (data[0] == '@') {
118 if (!tomoyo_is_correct_path(data, 0, 0, 0)) 118 if (!tomoyo_is_correct_word(data))
119 return false; 119 return false;
120 num->group = tomoyo_get_number_group(data + 1); 120 num->group = tomoyo_get_number_group(data + 1);
121 num->is_group = true; 121 num->is_group = true;
@@ -265,54 +265,29 @@ bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
265} 265}
266 266
267/** 267/**
268 * tomoyo_is_correct_path - Validate a pathname. 268 * tomoyo_is_correct_word2 - Validate a string.
269 * 269 *
270 * @filename: The pathname to check. 270 * @string: The string to check. May be non-'\0'-terminated.
271 * @start_type: Should the pathname start with '/'? 271 * @len: Length of @string.
272 * 1 = must / -1 = must not / 0 = don't care
273 * @pattern_type: Can the pathname contain a wildcard?
274 * 1 = must / -1 = must not / 0 = don't care
275 * @end_type: Should the pathname end with '/'?
276 * 1 = must / -1 = must not / 0 = don't care
277 * 272 *
278 * Check whether the given filename follows the naming rules. 273 * Check whether the given string follows the naming rules.
279 * Returns true if @filename follows the naming rules, false otherwise. 274 * Returns true if @string follows the naming rules, false otherwise.
280 */ 275 */
281bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 276static bool tomoyo_is_correct_word2(const char *string, size_t len)
282 const s8 pattern_type, const s8 end_type)
283{ 277{
284 const char *const start = filename; 278 const char *const start = string;
285 bool in_repetition = false; 279 bool in_repetition = false;
286 bool contains_pattern = false;
287 unsigned char c; 280 unsigned char c;
288 unsigned char d; 281 unsigned char d;
289 unsigned char e; 282 unsigned char e;
290 283 if (!len)
291 if (!filename)
292 goto out; 284 goto out;
293 c = *filename; 285 while (len--) {
294 if (start_type == 1) { /* Must start with '/' */ 286 c = *string++;
295 if (c != '/')
296 goto out;
297 } else if (start_type == -1) { /* Must not start with '/' */
298 if (c == '/')
299 goto out;
300 }
301 if (c)
302 c = *(filename + strlen(filename) - 1);
303 if (end_type == 1) { /* Must end with '/' */
304 if (c != '/')
305 goto out;
306 } else if (end_type == -1) { /* Must not end with '/' */
307 if (c == '/')
308 goto out;
309 }
310 while (1) {
311 c = *filename++;
312 if (!c)
313 break;
314 if (c == '\\') { 287 if (c == '\\') {
315 c = *filename++; 288 if (!len--)
289 goto out;
290 c = *string++;
316 switch (c) { 291 switch (c) {
317 case '\\': /* "\\" */ 292 case '\\': /* "\\" */
318 continue; 293 continue;
@@ -326,21 +301,14 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
326 case 'a': /* "\a" */ 301 case 'a': /* "\a" */
327 case 'A': /* "\A" */ 302 case 'A': /* "\A" */
328 case '-': /* "\-" */ 303 case '-': /* "\-" */
329 if (pattern_type == -1)
330 break; /* Must not contain pattern */
331 contains_pattern = true;
332 continue; 304 continue;
333 case '{': /* "/\{" */ 305 case '{': /* "/\{" */
334 if (filename - 3 < start || 306 if (string - 3 < start || *(string - 3) != '/')
335 *(filename - 3) != '/')
336 break; 307 break;
337 if (pattern_type == -1)
338 break; /* Must not contain pattern */
339 contains_pattern = true;
340 in_repetition = true; 308 in_repetition = true;
341 continue; 309 continue;
342 case '}': /* "\}/" */ 310 case '}': /* "\}/" */
343 if (*filename != '/') 311 if (*string != '/')
344 break; 312 break;
345 if (!in_repetition) 313 if (!in_repetition)
346 break; 314 break;
@@ -350,11 +318,11 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
350 case '1': 318 case '1':
351 case '2': 319 case '2':
352 case '3': 320 case '3':
353 d = *filename++; 321 if (!len-- || !len--)
354 if (d < '0' || d > '7')
355 break; 322 break;
356 e = *filename++; 323 d = *string++;
357 if (e < '0' || e > '7') 324 e = *string++;
325 if (d < '0' || d > '7' || e < '0' || e > '7')
358 break; 326 break;
359 c = tomoyo_make_byte(c, d, e); 327 c = tomoyo_make_byte(c, d, e);
360 if (tomoyo_is_invalid(c)) 328 if (tomoyo_is_invalid(c))
@@ -367,10 +335,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
367 goto out; 335 goto out;
368 } 336 }
369 } 337 }
370 if (pattern_type == 1) { /* Must contain pattern */
371 if (!contains_pattern)
372 goto out;
373 }
374 if (in_repetition) 338 if (in_repetition)
375 goto out; 339 goto out;
376 return true; 340 return true;
@@ -379,58 +343,58 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
379} 343}
380 344
381/** 345/**
346 * tomoyo_is_correct_word - Validate a string.
347 *
348 * @string: The string to check.
349 *
350 * Check whether the given string follows the naming rules.
351 * Returns true if @string follows the naming rules, false otherwise.
352 */
353bool tomoyo_is_correct_word(const char *string)
354{
355 return tomoyo_is_correct_word2(string, strlen(string));
356}
357
358/**
359 * tomoyo_is_correct_path - Validate a pathname.
360 *
361 * @filename: The pathname to check.
362 *
363 * Check whether the given pathname follows the naming rules.
364 * Returns true if @filename follows the naming rules, false otherwise.
365 */
366bool tomoyo_is_correct_path(const char *filename)
367{
368 return *filename == '/' && tomoyo_is_correct_word(filename);
369}
370
371/**
382 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules. 372 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules.
383 * 373 *
384 * @domainname: The domainname to check. 374 * @domainname: The domainname to check.
385 * 375 *
386 * Returns true if @domainname follows the naming rules, false otherwise. 376 * Returns true if @domainname follows the naming rules, false otherwise.
387 */ 377 */
388bool tomoyo_is_correct_domain(const unsigned char *domainname) 378bool tomoyo_is_correct_domain(const unsigned char *domainname)
389{ 379{
390 unsigned char c;
391 unsigned char d;
392 unsigned char e;
393
394 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 380 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
395 TOMOYO_ROOT_NAME_LEN)) 381 TOMOYO_ROOT_NAME_LEN))
396 goto out; 382 goto out;
397 domainname += TOMOYO_ROOT_NAME_LEN; 383 domainname += TOMOYO_ROOT_NAME_LEN;
398 if (!*domainname) 384 if (!*domainname)
399 return true; 385 return true;
400 do { 386 if (*domainname++ != ' ')
401 if (*domainname++ != ' ') 387 goto out;
402 goto out; 388 while (1) {
403 if (*domainname++ != '/') 389 const unsigned char *cp = strchr(domainname, ' ');
390 if (!cp)
391 break;
392 if (*domainname != '/' ||
393 !tomoyo_is_correct_word2(domainname, cp - domainname - 1))
404 goto out; 394 goto out;
405 while ((c = *domainname) != '\0' && c != ' ') { 395 domainname = cp + 1;
406 domainname++; 396 }
407 if (c == '\\') { 397 return tomoyo_is_correct_path(domainname);
408 c = *domainname++;
409 switch ((c)) {
410 case '\\': /* "\\" */
411 continue;
412 case '0': /* "\ooo" */
413 case '1':
414 case '2':
415 case '3':
416 d = *domainname++;
417 if (d < '0' || d > '7')
418 break;
419 e = *domainname++;
420 if (e < '0' || e > '7')
421 break;
422 c = tomoyo_make_byte(c, d, e);
423 if (tomoyo_is_invalid(c))
424 /* pattern is not \000 */
425 continue;
426 }
427 goto out;
428 } else if (tomoyo_is_invalid(c)) {
429 goto out;
430 }
431 }
432 } while (*domainname);
433 return true;
434 out: 398 out:
435 return false; 399 return false;
436} 400}