diff options
Diffstat (limited to 'security/tomoyo')
-rw-r--r-- | security/tomoyo/common.c | 2 | ||||
-rw-r--r-- | security/tomoyo/common.h | 7 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 21 | ||||
-rw-r--r-- | security/tomoyo/file.c | 37 | ||||
-rw-r--r-- | security/tomoyo/number_group.c | 3 | ||||
-rw-r--r-- | security/tomoyo/path_group.c | 17 | ||||
-rw-r--r-- | security/tomoyo/util.c | 154 |
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. */ |
673 | bool tomoyo_is_correct_domain(const unsigned char *domainname); | 673 | bool tomoyo_is_correct_domain(const unsigned char *domainname); |
674 | /* Check whether the token is correct. */ | 674 | /* Check whether the token is correct. */ |
675 | bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | 675 | bool tomoyo_is_correct_path(const char *filename); |
676 | const s8 pattern_type, const s8 end_type); | 676 | bool 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. */ |
678 | bool tomoyo_is_domain_def(const unsigned char *buffer); | 678 | bool tomoyo_is_domain_def(const unsigned char *buffer); |
679 | bool tomoyo_parse_name_union(const char *filename, | 679 | bool 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. */ |
682 | bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, | 682 | bool 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. */ |
686 | bool tomoyo_number_matches_group(const unsigned long min, | 685 | bool 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 | ||
72 | static 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 | |||
85 | void tomoyo_put_number_union(struct tomoyo_number_union *ptr) | 72 | void 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 | */ |
699 | static int tomoyo_path_acl(const struct tomoyo_request_info *r, | 686 | static 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 | */ |
150 | bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, | 148 | bool 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, | |||
89 | bool tomoyo_parse_name_union(const char *filename, | 89 | bool 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 | */ |
281 | bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | 276 | static 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 | */ | ||
353 | bool 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 | */ | ||
366 | bool 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 | */ |
388 | bool tomoyo_is_correct_domain(const unsigned char *domainname) | 378 | bool 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 | } |