aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-14 20:23:26 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:34:29 -0400
commit36f5e1ffbf2bb951105ae4e261bcc1de3eaf510c (patch)
tree80e01278296477b4d30288081267d35ff771d720 /security/tomoyo/domain.c
parent82e0f001a4c1112dcff9cafa9812a33889ad9b8a (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/tomoyo/domain.c')
-rw-r--r--security/tomoyo/domain.c184
1 files changed, 103 insertions, 81 deletions
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 @@
16struct tomoyo_domain_info tomoyo_kernel_domain; 16struct 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 */
31int 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 */
162LIST_HEAD(tomoyo_domain_initializer_list); 205LIST_HEAD(tomoyo_domain_initializer_list);
163 206
207static 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 */
374LIST_HEAD(tomoyo_domain_keeper_list); 413LIST_HEAD(tomoyo_domain_keeper_list);
375 414
415static 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 */
566LIST_HEAD(tomoyo_aggregator_list); 600LIST_HEAD(tomoyo_aggregator_list);
567 601
602static 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 */
700LIST_HEAD(tomoyo_alias_list); 728LIST_HEAD(tomoyo_alias_list);
701 729
730static 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);