diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-14 20:23:26 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:29 -0400 |
commit | 36f5e1ffbf2bb951105ae4e261bcc1de3eaf510c (patch) | |
tree | 80e01278296477b4d30288081267d35ff771d720 /security | |
parent | 82e0f001a4c1112dcff9cafa9812a33889ad9b8a (diff) |
TOMOYO: Use callback for updating entries.
Use common code for elements using "struct list_head" + "bool" structure.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/tomoyo/common.c | 35 | ||||
-rw-r--r-- | security/tomoyo/common.h | 39 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 184 | ||||
-rw-r--r-- | security/tomoyo/file.c | 107 | ||||
-rw-r--r-- | security/tomoyo/number_group.c | 45 | ||||
-rw-r--r-- | security/tomoyo/path_group.c | 32 |
6 files changed, 190 insertions, 252 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 7bfad45fcd61..4ee47af0917d 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -469,6 +469,15 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head) | |||
469 | */ | 469 | */ |
470 | LIST_HEAD(tomoyo_policy_manager_list); | 470 | LIST_HEAD(tomoyo_policy_manager_list); |
471 | 471 | ||
472 | static bool tomoyo_same_manager_entry(const struct tomoyo_acl_head *a, | ||
473 | const struct tomoyo_acl_head *b) | ||
474 | { | ||
475 | return container_of(a, struct tomoyo_policy_manager_entry, head) | ||
476 | ->manager == | ||
477 | container_of(b, struct tomoyo_policy_manager_entry, head) | ||
478 | ->manager; | ||
479 | } | ||
480 | |||
472 | /** | 481 | /** |
473 | * tomoyo_update_manager_entry - Add a manager entry. | 482 | * tomoyo_update_manager_entry - Add a manager entry. |
474 | * | 483 | * |
@@ -482,9 +491,8 @@ LIST_HEAD(tomoyo_policy_manager_list); | |||
482 | static int tomoyo_update_manager_entry(const char *manager, | 491 | static int tomoyo_update_manager_entry(const char *manager, |
483 | const bool is_delete) | 492 | const bool is_delete) |
484 | { | 493 | { |
485 | struct tomoyo_policy_manager_entry *ptr; | ||
486 | struct tomoyo_policy_manager_entry e = { }; | 494 | struct tomoyo_policy_manager_entry e = { }; |
487 | int error = is_delete ? -ENOENT : -ENOMEM; | 495 | int error; |
488 | 496 | ||
489 | if (tomoyo_is_domain_def(manager)) { | 497 | if (tomoyo_is_domain_def(manager)) { |
490 | if (!tomoyo_is_correct_domain(manager)) | 498 | if (!tomoyo_is_correct_domain(manager)) |
@@ -497,26 +505,9 @@ static int tomoyo_update_manager_entry(const char *manager, | |||
497 | e.manager = tomoyo_get_name(manager); | 505 | e.manager = tomoyo_get_name(manager); |
498 | if (!e.manager) | 506 | if (!e.manager) |
499 | return -ENOMEM; | 507 | return -ENOMEM; |
500 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 508 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
501 | goto out; | 509 | &tomoyo_policy_manager_list, |
502 | list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, head.list) { | 510 | tomoyo_same_manager_entry); |
503 | if (ptr->manager != e.manager) | ||
504 | continue; | ||
505 | ptr->head.is_deleted = is_delete; | ||
506 | error = 0; | ||
507 | break; | ||
508 | } | ||
509 | if (!is_delete && error) { | ||
510 | struct tomoyo_policy_manager_entry *entry = | ||
511 | tomoyo_commit_ok(&e, sizeof(e)); | ||
512 | if (entry) { | ||
513 | list_add_tail_rcu(&entry->head.list, | ||
514 | &tomoyo_policy_manager_list); | ||
515 | error = 0; | ||
516 | } | ||
517 | } | ||
518 | mutex_unlock(&tomoyo_policy_lock); | ||
519 | out: | ||
520 | tomoyo_put_name(e.manager); | 511 | tomoyo_put_name(e.manager); |
521 | return error; | 512 | return error; |
522 | } | 513 | } |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 0ab6e86f90aa..c8ab7553c48c 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -913,6 +913,12 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, | |||
913 | bool (*merge_duplicate) (struct tomoyo_acl_info *, | 913 | bool (*merge_duplicate) (struct tomoyo_acl_info *, |
914 | struct tomoyo_acl_info *, | 914 | struct tomoyo_acl_info *, |
915 | const bool)); | 915 | const bool)); |
916 | int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, | ||
917 | bool is_delete, struct list_head *list, | ||
918 | bool (*check_duplicate) (const struct tomoyo_acl_head | ||
919 | *, | ||
920 | const struct tomoyo_acl_head | ||
921 | *)); | ||
916 | 922 | ||
917 | /********** External variable definitions. **********/ | 923 | /********** External variable definitions. **********/ |
918 | 924 | ||
@@ -1042,39 +1048,6 @@ static inline bool tomoyo_is_same_number_union | |||
1042 | p1->max_type == p2->max_type && p1->is_group == p2->is_group; | 1048 | p1->max_type == p2->max_type && p1->is_group == p2->is_group; |
1043 | } | 1049 | } |
1044 | 1050 | ||
1045 | static inline bool tomoyo_is_same_domain_initializer_entry | ||
1046 | (const struct tomoyo_domain_initializer_entry *p1, | ||
1047 | const struct tomoyo_domain_initializer_entry *p2) | ||
1048 | { | ||
1049 | return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name | ||
1050 | && p1->domainname == p2->domainname | ||
1051 | && p1->program == p2->program; | ||
1052 | } | ||
1053 | |||
1054 | static inline bool tomoyo_is_same_domain_keeper_entry | ||
1055 | (const struct tomoyo_domain_keeper_entry *p1, | ||
1056 | const struct tomoyo_domain_keeper_entry *p2) | ||
1057 | { | ||
1058 | return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name | ||
1059 | && p1->domainname == p2->domainname | ||
1060 | && p1->program == p2->program; | ||
1061 | } | ||
1062 | |||
1063 | static inline bool tomoyo_is_same_aggregator_entry | ||
1064 | (const struct tomoyo_aggregator_entry *p1, | ||
1065 | const struct tomoyo_aggregator_entry *p2) | ||
1066 | { | ||
1067 | return p1->original_name == p2->original_name && | ||
1068 | p1->aggregated_name == p2->aggregated_name; | ||
1069 | } | ||
1070 | |||
1071 | static inline bool tomoyo_is_same_alias_entry | ||
1072 | (const struct tomoyo_alias_entry *p1, const struct tomoyo_alias_entry *p2) | ||
1073 | { | ||
1074 | return p1->original_name == p2->original_name && | ||
1075 | p1->aliased_name == p2->aliased_name; | ||
1076 | } | ||
1077 | |||
1078 | /** | 1051 | /** |
1079 | * list_for_each_cookie - iterate over a list with cookie. | 1052 | * list_for_each_cookie - iterate over a list with cookie. |
1080 | * @pos: the &struct list_head to use as a loop cursor. | 1053 | * @pos: the &struct list_head to use as a loop cursor. |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 60297da6adcf..fe621af46c2e 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -16,6 +16,49 @@ | |||
16 | struct tomoyo_domain_info tomoyo_kernel_domain; | 16 | struct tomoyo_domain_info tomoyo_kernel_domain; |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * tomoyo_update_policy - Update an entry for exception policy. | ||
20 | * | ||
21 | * @new_entry: Pointer to "struct tomoyo_acl_info". | ||
22 | * @size: Size of @new_entry in bytes. | ||
23 | * @is_delete: True if it is a delete request. | ||
24 | * @list: Pointer to "struct list_head". | ||
25 | * @check_duplicate: Callback function to find duplicated entry. | ||
26 | * | ||
27 | * Returns 0 on success, negative value otherwise. | ||
28 | * | ||
29 | * Caller holds tomoyo_read_lock(). | ||
30 | */ | ||
31 | int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, | ||
32 | bool is_delete, struct list_head *list, | ||
33 | bool (*check_duplicate) (const struct tomoyo_acl_head | ||
34 | *, | ||
35 | const struct tomoyo_acl_head | ||
36 | *)) | ||
37 | { | ||
38 | int error = is_delete ? -ENOENT : -ENOMEM; | ||
39 | struct tomoyo_acl_head *entry; | ||
40 | |||
41 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | ||
42 | return -ENOMEM; | ||
43 | list_for_each_entry_rcu(entry, list, list) { | ||
44 | if (!check_duplicate(entry, new_entry)) | ||
45 | continue; | ||
46 | entry->is_deleted = is_delete; | ||
47 | error = 0; | ||
48 | break; | ||
49 | } | ||
50 | if (error && !is_delete) { | ||
51 | entry = tomoyo_commit_ok(new_entry, size); | ||
52 | if (entry) { | ||
53 | list_add_tail_rcu(&entry->list, list); | ||
54 | error = 0; | ||
55 | } | ||
56 | } | ||
57 | mutex_unlock(&tomoyo_policy_lock); | ||
58 | return error; | ||
59 | } | ||
60 | |||
61 | /** | ||
19 | * tomoyo_update_domain - Update an entry for domain policy. | 62 | * tomoyo_update_domain - Update an entry for domain policy. |
20 | * | 63 | * |
21 | * @new_entry: Pointer to "struct tomoyo_acl_info". | 64 | * @new_entry: Pointer to "struct tomoyo_acl_info". |
@@ -161,6 +204,20 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain) | |||
161 | */ | 204 | */ |
162 | LIST_HEAD(tomoyo_domain_initializer_list); | 205 | LIST_HEAD(tomoyo_domain_initializer_list); |
163 | 206 | ||
207 | static bool tomoyo_same_domain_initializer_entry(const struct tomoyo_acl_head * | ||
208 | a, | ||
209 | const struct tomoyo_acl_head * | ||
210 | b) | ||
211 | { | ||
212 | const struct tomoyo_domain_initializer_entry *p1 = | ||
213 | container_of(a, typeof(*p1), head); | ||
214 | const struct tomoyo_domain_initializer_entry *p2 = | ||
215 | container_of(b, typeof(*p2), head); | ||
216 | return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name | ||
217 | && p1->domainname == p2->domainname | ||
218 | && p1->program == p2->program; | ||
219 | } | ||
220 | |||
164 | /** | 221 | /** |
165 | * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list. | 222 | * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list. |
166 | * | 223 | * |
@@ -178,7 +235,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname, | |||
178 | const bool is_not, | 235 | const bool is_not, |
179 | const bool is_delete) | 236 | const bool is_delete) |
180 | { | 237 | { |
181 | struct tomoyo_domain_initializer_entry *ptr; | ||
182 | struct tomoyo_domain_initializer_entry e = { .is_not = is_not }; | 238 | struct tomoyo_domain_initializer_entry e = { .is_not = is_not }; |
183 | int error = is_delete ? -ENOENT : -ENOMEM; | 239 | int error = is_delete ? -ENOENT : -ENOMEM; |
184 | 240 | ||
@@ -197,26 +253,9 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname, | |||
197 | e.program = tomoyo_get_name(program); | 253 | e.program = tomoyo_get_name(program); |
198 | if (!e.program) | 254 | if (!e.program) |
199 | goto out; | 255 | goto out; |
200 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 256 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
201 | goto out; | 257 | &tomoyo_domain_initializer_list, |
202 | list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, | 258 | tomoyo_same_domain_initializer_entry); |
203 | head.list) { | ||
204 | if (!tomoyo_is_same_domain_initializer_entry(ptr, &e)) | ||
205 | continue; | ||
206 | ptr->head.is_deleted = is_delete; | ||
207 | error = 0; | ||
208 | break; | ||
209 | } | ||
210 | if (!is_delete && error) { | ||
211 | struct tomoyo_domain_initializer_entry *entry = | ||
212 | tomoyo_commit_ok(&e, sizeof(e)); | ||
213 | if (entry) { | ||
214 | list_add_tail_rcu(&entry->head.list, | ||
215 | &tomoyo_domain_initializer_list); | ||
216 | error = 0; | ||
217 | } | ||
218 | } | ||
219 | mutex_unlock(&tomoyo_policy_lock); | ||
220 | out: | 259 | out: |
221 | tomoyo_put_name(e.domainname); | 260 | tomoyo_put_name(e.domainname); |
222 | tomoyo_put_name(e.program); | 261 | tomoyo_put_name(e.program); |
@@ -373,6 +412,18 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info * | |||
373 | */ | 412 | */ |
374 | LIST_HEAD(tomoyo_domain_keeper_list); | 413 | LIST_HEAD(tomoyo_domain_keeper_list); |
375 | 414 | ||
415 | static bool tomoyo_same_domain_keeper_entry(const struct tomoyo_acl_head *a, | ||
416 | const struct tomoyo_acl_head *b) | ||
417 | { | ||
418 | const struct tomoyo_domain_keeper_entry *p1 = | ||
419 | container_of(a, typeof(*p1), head); | ||
420 | const struct tomoyo_domain_keeper_entry *p2 = | ||
421 | container_of(b, typeof(*p2), head); | ||
422 | return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name | ||
423 | && p1->domainname == p2->domainname | ||
424 | && p1->program == p2->program; | ||
425 | } | ||
426 | |||
376 | /** | 427 | /** |
377 | * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list. | 428 | * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list. |
378 | * | 429 | * |
@@ -390,7 +441,6 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname, | |||
390 | const bool is_not, | 441 | const bool is_not, |
391 | const bool is_delete) | 442 | const bool is_delete) |
392 | { | 443 | { |
393 | struct tomoyo_domain_keeper_entry *ptr; | ||
394 | struct tomoyo_domain_keeper_entry e = { .is_not = is_not }; | 444 | struct tomoyo_domain_keeper_entry e = { .is_not = is_not }; |
395 | int error = is_delete ? -ENOENT : -ENOMEM; | 445 | int error = is_delete ? -ENOENT : -ENOMEM; |
396 | 446 | ||
@@ -409,25 +459,9 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname, | |||
409 | e.domainname = tomoyo_get_name(domainname); | 459 | e.domainname = tomoyo_get_name(domainname); |
410 | if (!e.domainname) | 460 | if (!e.domainname) |
411 | goto out; | 461 | goto out; |
412 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 462 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
413 | goto out; | 463 | &tomoyo_domain_keeper_list, |
414 | list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, head.list) { | 464 | tomoyo_same_domain_keeper_entry); |
415 | if (!tomoyo_is_same_domain_keeper_entry(ptr, &e)) | ||
416 | continue; | ||
417 | ptr->head.is_deleted = is_delete; | ||
418 | error = 0; | ||
419 | break; | ||
420 | } | ||
421 | if (!is_delete && error) { | ||
422 | struct tomoyo_domain_keeper_entry *entry = | ||
423 | tomoyo_commit_ok(&e, sizeof(e)); | ||
424 | if (entry) { | ||
425 | list_add_tail_rcu(&entry->head.list, | ||
426 | &tomoyo_domain_keeper_list); | ||
427 | error = 0; | ||
428 | } | ||
429 | } | ||
430 | mutex_unlock(&tomoyo_policy_lock); | ||
431 | out: | 465 | out: |
432 | tomoyo_put_name(e.domainname); | 466 | tomoyo_put_name(e.domainname); |
433 | tomoyo_put_name(e.program); | 467 | tomoyo_put_name(e.program); |
@@ -565,6 +599,17 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname, | |||
565 | */ | 599 | */ |
566 | LIST_HEAD(tomoyo_aggregator_list); | 600 | LIST_HEAD(tomoyo_aggregator_list); |
567 | 601 | ||
602 | static bool tomoyo_same_aggregator_entry(const struct tomoyo_acl_head *a, | ||
603 | const struct tomoyo_acl_head *b) | ||
604 | { | ||
605 | const struct tomoyo_aggregator_entry *p1 = container_of(a, typeof(*p1), | ||
606 | head); | ||
607 | const struct tomoyo_aggregator_entry *p2 = container_of(b, typeof(*p2), | ||
608 | head); | ||
609 | return p1->original_name == p2->original_name && | ||
610 | p1->aggregated_name == p2->aggregated_name; | ||
611 | } | ||
612 | |||
568 | /** | 613 | /** |
569 | * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator_entry" list. | 614 | * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator_entry" list. |
570 | * | 615 | * |
@@ -580,7 +625,6 @@ static int tomoyo_update_aggregator_entry(const char *original_name, | |||
580 | const char *aggregated_name, | 625 | const char *aggregated_name, |
581 | const bool is_delete) | 626 | const bool is_delete) |
582 | { | 627 | { |
583 | struct tomoyo_aggregator_entry *ptr; | ||
584 | struct tomoyo_aggregator_entry e = { }; | 628 | struct tomoyo_aggregator_entry e = { }; |
585 | int error = is_delete ? -ENOENT : -ENOMEM; | 629 | int error = is_delete ? -ENOENT : -ENOMEM; |
586 | 630 | ||
@@ -592,25 +636,9 @@ static int tomoyo_update_aggregator_entry(const char *original_name, | |||
592 | if (!e.original_name || !e.aggregated_name || | 636 | if (!e.original_name || !e.aggregated_name || |
593 | e.aggregated_name->is_patterned) /* No patterns allowed. */ | 637 | e.aggregated_name->is_patterned) /* No patterns allowed. */ |
594 | goto out; | 638 | goto out; |
595 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 639 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
596 | goto out; | 640 | &tomoyo_aggregator_list, |
597 | list_for_each_entry_rcu(ptr, &tomoyo_aggregator_list, head.list) { | 641 | tomoyo_same_aggregator_entry); |
598 | if (!tomoyo_is_same_aggregator_entry(ptr, &e)) | ||
599 | continue; | ||
600 | ptr->head.is_deleted = is_delete; | ||
601 | error = 0; | ||
602 | break; | ||
603 | } | ||
604 | if (!is_delete && error) { | ||
605 | struct tomoyo_aggregator_entry *entry = | ||
606 | tomoyo_commit_ok(&e, sizeof(e)); | ||
607 | if (entry) { | ||
608 | list_add_tail_rcu(&entry->head.list, | ||
609 | &tomoyo_aggregator_list); | ||
610 | error = 0; | ||
611 | } | ||
612 | } | ||
613 | mutex_unlock(&tomoyo_policy_lock); | ||
614 | out: | 642 | out: |
615 | tomoyo_put_name(e.original_name); | 643 | tomoyo_put_name(e.original_name); |
616 | tomoyo_put_name(e.aggregated_name); | 644 | tomoyo_put_name(e.aggregated_name); |
@@ -699,6 +727,17 @@ int tomoyo_write_aggregator_policy(char *data, const bool is_delete) | |||
699 | */ | 727 | */ |
700 | LIST_HEAD(tomoyo_alias_list); | 728 | LIST_HEAD(tomoyo_alias_list); |
701 | 729 | ||
730 | static bool tomoyo_same_alias_entry(const struct tomoyo_acl_head *a, | ||
731 | const struct tomoyo_acl_head *b) | ||
732 | { | ||
733 | const struct tomoyo_alias_entry *p1 = container_of(a, typeof(*p1), | ||
734 | head); | ||
735 | const struct tomoyo_alias_entry *p2 = container_of(b, typeof(*p2), | ||
736 | head); | ||
737 | return p1->original_name == p2->original_name && | ||
738 | p1->aliased_name == p2->aliased_name; | ||
739 | } | ||
740 | |||
702 | /** | 741 | /** |
703 | * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list. | 742 | * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list. |
704 | * | 743 | * |
@@ -714,7 +753,6 @@ static int tomoyo_update_alias_entry(const char *original_name, | |||
714 | const char *aliased_name, | 753 | const char *aliased_name, |
715 | const bool is_delete) | 754 | const bool is_delete) |
716 | { | 755 | { |
717 | struct tomoyo_alias_entry *ptr; | ||
718 | struct tomoyo_alias_entry e = { }; | 756 | struct tomoyo_alias_entry e = { }; |
719 | int error = is_delete ? -ENOENT : -ENOMEM; | 757 | int error = is_delete ? -ENOENT : -ENOMEM; |
720 | 758 | ||
@@ -726,25 +764,9 @@ static int tomoyo_update_alias_entry(const char *original_name, | |||
726 | if (!e.original_name || !e.aliased_name || | 764 | if (!e.original_name || !e.aliased_name || |
727 | e.original_name->is_patterned || e.aliased_name->is_patterned) | 765 | e.original_name->is_patterned || e.aliased_name->is_patterned) |
728 | goto out; /* No patterns allowed. */ | 766 | goto out; /* No patterns allowed. */ |
729 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 767 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
730 | goto out; | 768 | &tomoyo_alias_list, |
731 | list_for_each_entry_rcu(ptr, &tomoyo_alias_list, head.list) { | 769 | tomoyo_same_alias_entry); |
732 | if (!tomoyo_is_same_alias_entry(ptr, &e)) | ||
733 | continue; | ||
734 | ptr->head.is_deleted = is_delete; | ||
735 | error = 0; | ||
736 | break; | ||
737 | } | ||
738 | if (!is_delete && error) { | ||
739 | struct tomoyo_alias_entry *entry = | ||
740 | tomoyo_commit_ok(&e, sizeof(e)); | ||
741 | if (entry) { | ||
742 | list_add_tail_rcu(&entry->head.list, | ||
743 | &tomoyo_alias_list); | ||
744 | error = 0; | ||
745 | } | ||
746 | } | ||
747 | mutex_unlock(&tomoyo_policy_lock); | ||
748 | out: | 770 | out: |
749 | tomoyo_put_name(e.original_name); | 771 | tomoyo_put_name(e.original_name); |
750 | tomoyo_put_name(e.aliased_name); | 772 | tomoyo_put_name(e.aliased_name); |
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 09436d11f298..8015719926d5 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -253,6 +253,15 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
253 | */ | 253 | */ |
254 | LIST_HEAD(tomoyo_globally_readable_list); | 254 | LIST_HEAD(tomoyo_globally_readable_list); |
255 | 255 | ||
256 | static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, | ||
257 | const struct tomoyo_acl_head *b) | ||
258 | { | ||
259 | return container_of(a, struct tomoyo_globally_readable_file_entry, | ||
260 | head)->filename == | ||
261 | container_of(b, struct tomoyo_globally_readable_file_entry, | ||
262 | head)->filename; | ||
263 | } | ||
264 | |||
256 | /** | 265 | /** |
257 | * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. | 266 | * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. |
258 | * | 267 | * |
@@ -266,36 +275,17 @@ LIST_HEAD(tomoyo_globally_readable_list); | |||
266 | static int tomoyo_update_globally_readable_entry(const char *filename, | 275 | static int tomoyo_update_globally_readable_entry(const char *filename, |
267 | const bool is_delete) | 276 | const bool is_delete) |
268 | { | 277 | { |
269 | struct tomoyo_globally_readable_file_entry *ptr; | ||
270 | struct tomoyo_globally_readable_file_entry e = { }; | 278 | struct tomoyo_globally_readable_file_entry e = { }; |
271 | int error = is_delete ? -ENOENT : -ENOMEM; | 279 | int error; |
272 | 280 | ||
273 | if (!tomoyo_is_correct_word(filename)) | 281 | if (!tomoyo_is_correct_word(filename)) |
274 | return -EINVAL; | 282 | return -EINVAL; |
275 | e.filename = tomoyo_get_name(filename); | 283 | e.filename = tomoyo_get_name(filename); |
276 | if (!e.filename) | 284 | if (!e.filename) |
277 | return -ENOMEM; | 285 | return -ENOMEM; |
278 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 286 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
279 | goto out; | 287 | &tomoyo_globally_readable_list, |
280 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, | 288 | tomoyo_same_globally_readable); |
281 | head.list) { | ||
282 | if (ptr->filename != e.filename) | ||
283 | continue; | ||
284 | ptr->head.is_deleted = is_delete; | ||
285 | error = 0; | ||
286 | break; | ||
287 | } | ||
288 | if (!is_delete && error) { | ||
289 | struct tomoyo_globally_readable_file_entry *entry = | ||
290 | tomoyo_commit_ok(&e, sizeof(e)); | ||
291 | if (entry) { | ||
292 | list_add_tail_rcu(&entry->head.list, | ||
293 | &tomoyo_globally_readable_list); | ||
294 | error = 0; | ||
295 | } | ||
296 | } | ||
297 | mutex_unlock(&tomoyo_policy_lock); | ||
298 | out: | ||
299 | tomoyo_put_name(e.filename); | 289 | tomoyo_put_name(e.filename); |
300 | return error; | 290 | return error; |
301 | } | 291 | } |
@@ -402,6 +392,13 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) | |||
402 | */ | 392 | */ |
403 | LIST_HEAD(tomoyo_pattern_list); | 393 | LIST_HEAD(tomoyo_pattern_list); |
404 | 394 | ||
395 | static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, | ||
396 | const struct tomoyo_acl_head *b) | ||
397 | { | ||
398 | return container_of(a, struct tomoyo_pattern_entry, head)->pattern == | ||
399 | container_of(b, struct tomoyo_pattern_entry, head)->pattern; | ||
400 | } | ||
401 | |||
405 | /** | 402 | /** |
406 | * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. | 403 | * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. |
407 | * | 404 | * |
@@ -415,35 +412,17 @@ LIST_HEAD(tomoyo_pattern_list); | |||
415 | static int tomoyo_update_file_pattern_entry(const char *pattern, | 412 | static int tomoyo_update_file_pattern_entry(const char *pattern, |
416 | const bool is_delete) | 413 | const bool is_delete) |
417 | { | 414 | { |
418 | struct tomoyo_pattern_entry *ptr; | ||
419 | struct tomoyo_pattern_entry e = { }; | 415 | struct tomoyo_pattern_entry e = { }; |
420 | int error = is_delete ? -ENOENT : -ENOMEM; | 416 | int error; |
421 | 417 | ||
422 | if (!tomoyo_is_correct_word(pattern)) | 418 | if (!tomoyo_is_correct_word(pattern)) |
423 | return -EINVAL; | 419 | return -EINVAL; |
424 | e.pattern = tomoyo_get_name(pattern); | 420 | e.pattern = tomoyo_get_name(pattern); |
425 | if (!e.pattern) | 421 | if (!e.pattern) |
426 | return error; | 422 | return -ENOMEM; |
427 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 423 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
428 | goto out; | 424 | &tomoyo_pattern_list, |
429 | list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, head.list) { | 425 | tomoyo_same_pattern); |
430 | if (e.pattern != ptr->pattern) | ||
431 | continue; | ||
432 | ptr->head.is_deleted = is_delete; | ||
433 | error = 0; | ||
434 | break; | ||
435 | } | ||
436 | if (!is_delete && error) { | ||
437 | struct tomoyo_pattern_entry *entry = | ||
438 | tomoyo_commit_ok(&e, sizeof(e)); | ||
439 | if (entry) { | ||
440 | list_add_tail_rcu(&entry->head.list, | ||
441 | &tomoyo_pattern_list); | ||
442 | error = 0; | ||
443 | } | ||
444 | } | ||
445 | mutex_unlock(&tomoyo_policy_lock); | ||
446 | out: | ||
447 | tomoyo_put_name(e.pattern); | 426 | tomoyo_put_name(e.pattern); |
448 | return error; | 427 | return error; |
449 | } | 428 | } |
@@ -553,6 +532,14 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) | |||
553 | */ | 532 | */ |
554 | LIST_HEAD(tomoyo_no_rewrite_list); | 533 | LIST_HEAD(tomoyo_no_rewrite_list); |
555 | 534 | ||
535 | static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, | ||
536 | const struct tomoyo_acl_head *b) | ||
537 | { | ||
538 | return container_of(a, struct tomoyo_no_rewrite_entry, head)->pattern | ||
539 | == container_of(b, struct tomoyo_no_rewrite_entry, head) | ||
540 | ->pattern; | ||
541 | } | ||
542 | |||
556 | /** | 543 | /** |
557 | * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. | 544 | * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. |
558 | * | 545 | * |
@@ -566,35 +553,17 @@ LIST_HEAD(tomoyo_no_rewrite_list); | |||
566 | static int tomoyo_update_no_rewrite_entry(const char *pattern, | 553 | static int tomoyo_update_no_rewrite_entry(const char *pattern, |
567 | const bool is_delete) | 554 | const bool is_delete) |
568 | { | 555 | { |
569 | struct tomoyo_no_rewrite_entry *ptr; | ||
570 | struct tomoyo_no_rewrite_entry e = { }; | 556 | struct tomoyo_no_rewrite_entry e = { }; |
571 | int error = is_delete ? -ENOENT : -ENOMEM; | 557 | int error; |
572 | 558 | ||
573 | if (!tomoyo_is_correct_word(pattern)) | 559 | if (!tomoyo_is_correct_word(pattern)) |
574 | return -EINVAL; | 560 | return -EINVAL; |
575 | e.pattern = tomoyo_get_name(pattern); | 561 | e.pattern = tomoyo_get_name(pattern); |
576 | if (!e.pattern) | 562 | if (!e.pattern) |
577 | return error; | 563 | return -ENOMEM; |
578 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 564 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
579 | goto out; | 565 | &tomoyo_no_rewrite_list, |
580 | list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, head.list) { | 566 | tomoyo_same_no_rewrite); |
581 | if (ptr->pattern != e.pattern) | ||
582 | continue; | ||
583 | ptr->head.is_deleted = is_delete; | ||
584 | error = 0; | ||
585 | break; | ||
586 | } | ||
587 | if (!is_delete && error) { | ||
588 | struct tomoyo_no_rewrite_entry *entry = | ||
589 | tomoyo_commit_ok(&e, sizeof(e)); | ||
590 | if (entry) { | ||
591 | list_add_tail_rcu(&entry->head.list, | ||
592 | &tomoyo_no_rewrite_list); | ||
593 | error = 0; | ||
594 | } | ||
595 | } | ||
596 | mutex_unlock(&tomoyo_policy_lock); | ||
597 | out: | ||
598 | tomoyo_put_name(e.pattern); | 567 | tomoyo_put_name(e.pattern); |
599 | return error; | 568 | return error; |
600 | } | 569 | } |
diff --git a/security/tomoyo/number_group.c b/security/tomoyo/number_group.c index afc5b6972129..7266a7462c45 100644 --- a/security/tomoyo/number_group.c +++ b/security/tomoyo/number_group.c | |||
@@ -56,6 +56,18 @@ struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name) | |||
56 | return !error ? group : NULL; | 56 | return !error ? group : NULL; |
57 | } | 57 | } |
58 | 58 | ||
59 | static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, | ||
60 | const struct tomoyo_acl_head *b) | ||
61 | { | ||
62 | return !memcmp(&container_of(a, struct tomoyo_number_group_member, | ||
63 | head)->number, | ||
64 | &container_of(b, struct tomoyo_number_group_member, | ||
65 | head)->number, | ||
66 | sizeof(container_of(a, | ||
67 | struct tomoyo_number_group_member, | ||
68 | head)->number)); | ||
69 | } | ||
70 | |||
59 | /** | 71 | /** |
60 | * tomoyo_write_number_group_policy - Write "struct tomoyo_number_group" list. | 72 | * tomoyo_write_number_group_policy - Write "struct tomoyo_number_group" list. |
61 | * | 73 | * |
@@ -68,40 +80,19 @@ int tomoyo_write_number_group_policy(char *data, const bool is_delete) | |||
68 | { | 80 | { |
69 | struct tomoyo_number_group *group; | 81 | struct tomoyo_number_group *group; |
70 | struct tomoyo_number_group_member e = { }; | 82 | struct tomoyo_number_group_member e = { }; |
71 | struct tomoyo_number_group_member *member; | 83 | int error; |
72 | int error = is_delete ? -ENOENT : -ENOMEM; | ||
73 | char *w[2]; | 84 | char *w[2]; |
74 | if (!tomoyo_tokenize(data, w, sizeof(w))) | 85 | if (!tomoyo_tokenize(data, w, sizeof(w))) |
75 | return -EINVAL; | 86 | return -EINVAL; |
76 | if (!tomoyo_parse_number_union(w[1], &e.number)) | 87 | if (w[1][0] == '@' || !tomoyo_parse_number_union(w[1], &e.number) || |
77 | return -EINVAL; | 88 | e.number.values[0] > e.number.values[1]) |
78 | if (e.number.is_group || e.number.values[0] > e.number.values[1]) { | ||
79 | tomoyo_put_number_union(&e.number); | ||
80 | return -EINVAL; | 89 | return -EINVAL; |
81 | } | ||
82 | group = tomoyo_get_number_group(w[0]); | 90 | group = tomoyo_get_number_group(w[0]); |
83 | if (!group) | 91 | if (!group) |
84 | return -ENOMEM; | 92 | return -ENOMEM; |
85 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 93 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
86 | goto out; | 94 | &group->member_list, |
87 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 95 | tomoyo_same_number_group); |
88 | if (memcmp(&member->number, &e.number, sizeof(e.number))) | ||
89 | continue; | ||
90 | member->head.is_deleted = is_delete; | ||
91 | error = 0; | ||
92 | break; | ||
93 | } | ||
94 | if (!is_delete && error) { | ||
95 | struct tomoyo_number_group_member *entry = | ||
96 | tomoyo_commit_ok(&e, sizeof(e)); | ||
97 | if (entry) { | ||
98 | list_add_tail_rcu(&entry->head.list, | ||
99 | &group->member_list); | ||
100 | error = 0; | ||
101 | } | ||
102 | } | ||
103 | mutex_unlock(&tomoyo_policy_lock); | ||
104 | out: | ||
105 | tomoyo_put_number_group(group); | 96 | tomoyo_put_number_group(group); |
106 | return error; | 97 | return error; |
107 | } | 98 | } |
diff --git a/security/tomoyo/path_group.c b/security/tomoyo/path_group.c index 7838f7681297..5b71d8868453 100644 --- a/security/tomoyo/path_group.c +++ b/security/tomoyo/path_group.c | |||
@@ -54,6 +54,15 @@ struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name) | |||
54 | return !error ? group : NULL; | 54 | return !error ? group : NULL; |
55 | } | 55 | } |
56 | 56 | ||
57 | static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, | ||
58 | const struct tomoyo_acl_head *b) | ||
59 | { | ||
60 | return container_of(a, struct tomoyo_path_group_member, head) | ||
61 | ->member_name == | ||
62 | container_of(b, struct tomoyo_path_group_member, head) | ||
63 | ->member_name; | ||
64 | } | ||
65 | |||
57 | /** | 66 | /** |
58 | * tomoyo_write_path_group_policy - Write "struct tomoyo_path_group" list. | 67 | * tomoyo_write_path_group_policy - Write "struct tomoyo_path_group" list. |
59 | * | 68 | * |
@@ -65,7 +74,6 @@ struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name) | |||
65 | int tomoyo_write_path_group_policy(char *data, const bool is_delete) | 74 | int tomoyo_write_path_group_policy(char *data, const bool is_delete) |
66 | { | 75 | { |
67 | struct tomoyo_path_group *group; | 76 | struct tomoyo_path_group *group; |
68 | struct tomoyo_path_group_member *member; | ||
69 | struct tomoyo_path_group_member e = { }; | 77 | struct tomoyo_path_group_member e = { }; |
70 | int error = is_delete ? -ENOENT : -ENOMEM; | 78 | int error = is_delete ? -ENOENT : -ENOMEM; |
71 | char *w[2]; | 79 | char *w[2]; |
@@ -77,25 +85,9 @@ int tomoyo_write_path_group_policy(char *data, const bool is_delete) | |||
77 | e.member_name = tomoyo_get_name(w[1]); | 85 | e.member_name = tomoyo_get_name(w[1]); |
78 | if (!e.member_name) | 86 | if (!e.member_name) |
79 | goto out; | 87 | goto out; |
80 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 88 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
81 | goto out; | 89 | &group->member_list, |
82 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 90 | tomoyo_same_path_group); |
83 | if (member->member_name != e.member_name) | ||
84 | continue; | ||
85 | member->head.is_deleted = is_delete; | ||
86 | error = 0; | ||
87 | break; | ||
88 | } | ||
89 | if (!is_delete && error) { | ||
90 | struct tomoyo_path_group_member *entry = | ||
91 | tomoyo_commit_ok(&e, sizeof(e)); | ||
92 | if (entry) { | ||
93 | list_add_tail_rcu(&entry->head.list, | ||
94 | &group->member_list); | ||
95 | error = 0; | ||
96 | } | ||
97 | } | ||
98 | mutex_unlock(&tomoyo_policy_lock); | ||
99 | out: | 91 | out: |
100 | tomoyo_put_name(e.member_name); | 92 | tomoyo_put_name(e.member_name); |
101 | tomoyo_put_path_group(group); | 93 | tomoyo_put_path_group(group); |