aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}