aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.c35
-rw-r--r--security/tomoyo/common.h39
-rw-r--r--security/tomoyo/domain.c184
-rw-r--r--security/tomoyo/file.c107
-rw-r--r--security/tomoyo/number_group.c45
-rw-r--r--security/tomoyo/path_group.c32
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 */
470LIST_HEAD(tomoyo_policy_manager_list); 470LIST_HEAD(tomoyo_policy_manager_list);
471 471
472static 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);
482static int tomoyo_update_manager_entry(const char *manager, 491static 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));
916int 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
1045static 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
1054static 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
1063static 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
1071static 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 @@
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);
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 */
254LIST_HEAD(tomoyo_globally_readable_list); 254LIST_HEAD(tomoyo_globally_readable_list);
255 255
256static 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);
266static int tomoyo_update_globally_readable_entry(const char *filename, 275static 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 */
403LIST_HEAD(tomoyo_pattern_list); 393LIST_HEAD(tomoyo_pattern_list);
404 394
395static 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);
415static int tomoyo_update_file_pattern_entry(const char *pattern, 412static 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 */
554LIST_HEAD(tomoyo_no_rewrite_list); 533LIST_HEAD(tomoyo_no_rewrite_list);
555 534
535static 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);
566static int tomoyo_update_no_rewrite_entry(const char *pattern, 553static 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
59static 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
57static 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)
65int tomoyo_write_path_group_policy(char *data, const bool is_delete) 74int 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);