aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/domain.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r--security/tomoyo/domain.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index fcf52accce2b..2fd190168b7e 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -217,6 +217,8 @@ static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
217 * @is_delete: True if it is a delete request. 217 * @is_delete: True if it is a delete request.
218 * 218 *
219 * Returns 0 on success, negative value otherwise. 219 * Returns 0 on success, negative value otherwise.
220 *
221 * Caller holds tomoyo_read_lock().
220 */ 222 */
221static int tomoyo_update_domain_initializer_entry(const char *domainname, 223static int tomoyo_update_domain_initializer_entry(const char *domainname,
222 const char *program, 224 const char *program,
@@ -246,7 +248,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
246 if (!saved_program) 248 if (!saved_program)
247 return -ENOMEM; 249 return -ENOMEM;
248 down_write(&tomoyo_domain_initializer_list_lock); 250 down_write(&tomoyo_domain_initializer_list_lock);
249 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 251 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
250 if (ptr->is_not != is_not || 252 if (ptr->is_not != is_not ||
251 ptr->domainname != saved_domainname || 253 ptr->domainname != saved_domainname ||
252 ptr->program != saved_program) 254 ptr->program != saved_program)
@@ -266,7 +268,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
266 new_entry->program = saved_program; 268 new_entry->program = saved_program;
267 new_entry->is_not = is_not; 269 new_entry->is_not = is_not;
268 new_entry->is_last_name = is_last_name; 270 new_entry->is_last_name = is_last_name;
269 list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list); 271 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
270 error = 0; 272 error = 0;
271 out: 273 out:
272 up_write(&tomoyo_domain_initializer_list_lock); 274 up_write(&tomoyo_domain_initializer_list_lock);
@@ -279,13 +281,14 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
279 * @head: Pointer to "struct tomoyo_io_buffer". 281 * @head: Pointer to "struct tomoyo_io_buffer".
280 * 282 *
281 * Returns true on success, false otherwise. 283 * Returns true on success, false otherwise.
284 *
285 * Caller holds tomoyo_read_lock().
282 */ 286 */
283bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head) 287bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
284{ 288{
285 struct list_head *pos; 289 struct list_head *pos;
286 bool done = true; 290 bool done = true;
287 291
288 down_read(&tomoyo_domain_initializer_list_lock);
289 list_for_each_cookie(pos, head->read_var2, 292 list_for_each_cookie(pos, head->read_var2,
290 &tomoyo_domain_initializer_list) { 293 &tomoyo_domain_initializer_list) {
291 const char *no; 294 const char *no;
@@ -308,7 +311,6 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
308 if (!done) 311 if (!done)
309 break; 312 break;
310 } 313 }
311 up_read(&tomoyo_domain_initializer_list_lock);
312 return done; 314 return done;
313} 315}
314 316
@@ -320,6 +322,8 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
320 * @is_delete: True if it is a delete request. 322 * @is_delete: True if it is a delete request.
321 * 323 *
322 * Returns 0 on success, negative value otherwise. 324 * Returns 0 on success, negative value otherwise.
325 *
326 * Caller holds tomoyo_read_lock().
323 */ 327 */
324int tomoyo_write_domain_initializer_policy(char *data, const bool is_not, 328int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
325 const bool is_delete) 329 const bool is_delete)
@@ -345,6 +349,8 @@ int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
345 * 349 *
346 * Returns true if executing @program reinitializes domain transition, 350 * Returns true if executing @program reinitializes domain transition,
347 * false otherwise. 351 * false otherwise.
352 *
353 * Caller holds tomoyo_read_lock().
348 */ 354 */
349static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info * 355static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
350 domainname, 356 domainname,
@@ -355,8 +361,7 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
355 struct tomoyo_domain_initializer_entry *ptr; 361 struct tomoyo_domain_initializer_entry *ptr;
356 bool flag = false; 362 bool flag = false;
357 363
358 down_read(&tomoyo_domain_initializer_list_lock); 364 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
359 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
360 if (ptr->is_deleted) 365 if (ptr->is_deleted)
361 continue; 366 continue;
362 if (ptr->domainname) { 367 if (ptr->domainname) {
@@ -376,7 +381,6 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
376 } 381 }
377 flag = true; 382 flag = true;
378 } 383 }
379 up_read(&tomoyo_domain_initializer_list_lock);
380 return flag; 384 return flag;
381} 385}
382 386
@@ -430,6 +434,8 @@ static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
430 * @is_delete: True if it is a delete request. 434 * @is_delete: True if it is a delete request.
431 * 435 *
432 * Returns 0 on success, negative value otherwise. 436 * Returns 0 on success, negative value otherwise.
437 *
438 * Caller holds tomoyo_read_lock().
433 */ 439 */
434static int tomoyo_update_domain_keeper_entry(const char *domainname, 440static int tomoyo_update_domain_keeper_entry(const char *domainname,
435 const char *program, 441 const char *program,
@@ -459,7 +465,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
459 if (!saved_domainname) 465 if (!saved_domainname)
460 return -ENOMEM; 466 return -ENOMEM;
461 down_write(&tomoyo_domain_keeper_list_lock); 467 down_write(&tomoyo_domain_keeper_list_lock);
462 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 468 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
463 if (ptr->is_not != is_not || 469 if (ptr->is_not != is_not ||
464 ptr->domainname != saved_domainname || 470 ptr->domainname != saved_domainname ||
465 ptr->program != saved_program) 471 ptr->program != saved_program)
@@ -479,7 +485,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
479 new_entry->program = saved_program; 485 new_entry->program = saved_program;
480 new_entry->is_not = is_not; 486 new_entry->is_not = is_not;
481 new_entry->is_last_name = is_last_name; 487 new_entry->is_last_name = is_last_name;
482 list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list); 488 list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
483 error = 0; 489 error = 0;
484 out: 490 out:
485 up_write(&tomoyo_domain_keeper_list_lock); 491 up_write(&tomoyo_domain_keeper_list_lock);
@@ -493,6 +499,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
493 * @is_not: True if it is "no_keep_domain" entry. 499 * @is_not: True if it is "no_keep_domain" entry.
494 * @is_delete: True if it is a delete request. 500 * @is_delete: True if it is a delete request.
495 * 501 *
502 * Caller holds tomoyo_read_lock().
496 */ 503 */
497int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, 504int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
498 const bool is_delete) 505 const bool is_delete)
@@ -513,13 +520,14 @@ int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
513 * @head: Pointer to "struct tomoyo_io_buffer". 520 * @head: Pointer to "struct tomoyo_io_buffer".
514 * 521 *
515 * Returns true on success, false otherwise. 522 * Returns true on success, false otherwise.
523 *
524 * Caller holds tomoyo_read_lock().
516 */ 525 */
517bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head) 526bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
518{ 527{
519 struct list_head *pos; 528 struct list_head *pos;
520 bool done = true; 529 bool done = true;
521 530
522 down_read(&tomoyo_domain_keeper_list_lock);
523 list_for_each_cookie(pos, head->read_var2, 531 list_for_each_cookie(pos, head->read_var2,
524 &tomoyo_domain_keeper_list) { 532 &tomoyo_domain_keeper_list) {
525 struct tomoyo_domain_keeper_entry *ptr; 533 struct tomoyo_domain_keeper_entry *ptr;
@@ -542,7 +550,6 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
542 if (!done) 550 if (!done)
543 break; 551 break;
544 } 552 }
545 up_read(&tomoyo_domain_keeper_list_lock);
546 return done; 553 return done;
547} 554}
548 555
@@ -555,6 +562,8 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
555 * 562 *
556 * Returns true if executing @program supresses domain transition, 563 * Returns true if executing @program supresses domain transition,
557 * false otherwise. 564 * false otherwise.
565 *
566 * Caller holds tomoyo_read_lock().
558 */ 567 */
559static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname, 568static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
560 const struct tomoyo_path_info *program, 569 const struct tomoyo_path_info *program,
@@ -563,8 +572,7 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
563 struct tomoyo_domain_keeper_entry *ptr; 572 struct tomoyo_domain_keeper_entry *ptr;
564 bool flag = false; 573 bool flag = false;
565 574
566 down_read(&tomoyo_domain_keeper_list_lock); 575 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
567 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
568 if (ptr->is_deleted) 576 if (ptr->is_deleted)
569 continue; 577 continue;
570 if (!ptr->is_last_name) { 578 if (!ptr->is_last_name) {
@@ -582,7 +590,6 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
582 } 590 }
583 flag = true; 591 flag = true;
584 } 592 }
585 up_read(&tomoyo_domain_keeper_list_lock);
586 return flag; 593 return flag;
587} 594}
588 595
@@ -627,6 +634,8 @@ static DECLARE_RWSEM(tomoyo_alias_list_lock);
627 * @is_delete: True if it is a delete request. 634 * @is_delete: True if it is a delete request.
628 * 635 *
629 * Returns 0 on success, negative value otherwise. 636 * Returns 0 on success, negative value otherwise.
637 *
638 * Caller holds tomoyo_read_lock().
630 */ 639 */
631static int tomoyo_update_alias_entry(const char *original_name, 640static int tomoyo_update_alias_entry(const char *original_name,
632 const char *aliased_name, 641 const char *aliased_name,
@@ -646,7 +655,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
646 if (!saved_original_name || !saved_aliased_name) 655 if (!saved_original_name || !saved_aliased_name)
647 return -ENOMEM; 656 return -ENOMEM;
648 down_write(&tomoyo_alias_list_lock); 657 down_write(&tomoyo_alias_list_lock);
649 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 658 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
650 if (ptr->original_name != saved_original_name || 659 if (ptr->original_name != saved_original_name ||
651 ptr->aliased_name != saved_aliased_name) 660 ptr->aliased_name != saved_aliased_name)
652 continue; 661 continue;
@@ -663,7 +672,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
663 goto out; 672 goto out;
664 new_entry->original_name = saved_original_name; 673 new_entry->original_name = saved_original_name;
665 new_entry->aliased_name = saved_aliased_name; 674 new_entry->aliased_name = saved_aliased_name;
666 list_add_tail(&new_entry->list, &tomoyo_alias_list); 675 list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
667 error = 0; 676 error = 0;
668 out: 677 out:
669 up_write(&tomoyo_alias_list_lock); 678 up_write(&tomoyo_alias_list_lock);
@@ -676,13 +685,14 @@ static int tomoyo_update_alias_entry(const char *original_name,
676 * @head: Pointer to "struct tomoyo_io_buffer". 685 * @head: Pointer to "struct tomoyo_io_buffer".
677 * 686 *
678 * Returns true on success, false otherwise. 687 * Returns true on success, false otherwise.
688 *
689 * Caller holds tomoyo_read_lock().
679 */ 690 */
680bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head) 691bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
681{ 692{
682 struct list_head *pos; 693 struct list_head *pos;
683 bool done = true; 694 bool done = true;
684 695
685 down_read(&tomoyo_alias_list_lock);
686 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) { 696 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
687 struct tomoyo_alias_entry *ptr; 697 struct tomoyo_alias_entry *ptr;
688 698
@@ -695,7 +705,6 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
695 if (!done) 705 if (!done)
696 break; 706 break;
697 } 707 }
698 up_read(&tomoyo_alias_list_lock);
699 return done; 708 return done;
700} 709}
701 710
@@ -706,6 +715,8 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
706 * @is_delete: True if it is a delete request. 715 * @is_delete: True if it is a delete request.
707 * 716 *
708 * Returns 0 on success, negative value otherwise. 717 * Returns 0 on success, negative value otherwise.
718 *
719 * Caller holds tomoyo_read_lock().
709 */ 720 */
710int tomoyo_write_alias_policy(char *data, const bool is_delete) 721int tomoyo_write_alias_policy(char *data, const bool is_delete)
711{ 722{
@@ -724,6 +735,8 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete)
724 * @profile: Profile number to assign if the domain was newly created. 735 * @profile: Profile number to assign if the domain was newly created.
725 * 736 *
726 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 737 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
738 *
739 * Caller holds tomoyo_read_lock().
727 */ 740 */
728struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 741struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
729 domainname, 742 domainname,
@@ -742,7 +755,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
742 if (!saved_domainname) 755 if (!saved_domainname)
743 goto out; 756 goto out;
744 /* Can I reuse memory of deleted domain? */ 757 /* Can I reuse memory of deleted domain? */
745 list_for_each_entry(domain, &tomoyo_domain_list, list) { 758 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
746 struct task_struct *p; 759 struct task_struct *p;
747 struct tomoyo_acl_info *ptr; 760 struct tomoyo_acl_info *ptr;
748 bool flag; 761 bool flag;
@@ -760,7 +773,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
760 read_unlock(&tasklist_lock); 773 read_unlock(&tasklist_lock);
761 if (flag) 774 if (flag)
762 continue; 775 continue;
763 list_for_each_entry(ptr, &domain->acl_info_list, list) { 776 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
764 ptr->type |= TOMOYO_ACL_DELETED; 777 ptr->type |= TOMOYO_ACL_DELETED;
765 } 778 }
766 tomoyo_set_domain_flag(domain, true, domain->flags); 779 tomoyo_set_domain_flag(domain, true, domain->flags);
@@ -776,7 +789,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
776 INIT_LIST_HEAD(&domain->acl_info_list); 789 INIT_LIST_HEAD(&domain->acl_info_list);
777 domain->domainname = saved_domainname; 790 domain->domainname = saved_domainname;
778 domain->profile = profile; 791 domain->profile = profile;
779 list_add_tail(&domain->list, &tomoyo_domain_list); 792 list_add_tail_rcu(&domain->list, &tomoyo_domain_list);
780 } 793 }
781 out: 794 out:
782 up_write(&tomoyo_domain_list_lock); 795 up_write(&tomoyo_domain_list_lock);
@@ -789,6 +802,8 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
789 * @bprm: Pointer to "struct linux_binprm". 802 * @bprm: Pointer to "struct linux_binprm".
790 * 803 *
791 * Returns 0 on success, negative value otherwise. 804 * Returns 0 on success, negative value otherwise.
805 *
806 * Caller holds tomoyo_read_lock().
792 */ 807 */
793int tomoyo_find_next_domain(struct linux_binprm *bprm) 808int tomoyo_find_next_domain(struct linux_binprm *bprm)
794{ 809{
@@ -849,8 +864,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
849 if (tomoyo_pathcmp(&r, &s)) { 864 if (tomoyo_pathcmp(&r, &s)) {
850 struct tomoyo_alias_entry *ptr; 865 struct tomoyo_alias_entry *ptr;
851 /* Is this program allowed to be called via symbolic links? */ 866 /* Is this program allowed to be called via symbolic links? */
852 down_read(&tomoyo_alias_list_lock); 867 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
853 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
854 if (ptr->is_deleted || 868 if (ptr->is_deleted ||
855 tomoyo_pathcmp(&r, ptr->original_name) || 869 tomoyo_pathcmp(&r, ptr->original_name) ||
856 tomoyo_pathcmp(&s, ptr->aliased_name)) 870 tomoyo_pathcmp(&s, ptr->aliased_name))
@@ -861,7 +875,6 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
861 tomoyo_fill_path_info(&r); 875 tomoyo_fill_path_info(&r);
862 break; 876 break;
863 } 877 }
864 up_read(&tomoyo_alias_list_lock);
865 } 878 }
866 879
867 /* Check execute permission. */ 880 /* Check execute permission. */
@@ -892,9 +905,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
892 } 905 }
893 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN) 906 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN)
894 goto done; 907 goto done;
895 down_read(&tomoyo_domain_list_lock);
896 domain = tomoyo_find_domain(new_domain_name); 908 domain = tomoyo_find_domain(new_domain_name);
897 up_read(&tomoyo_domain_list_lock);
898 if (domain) 909 if (domain)
899 goto done; 910 goto done;
900 if (is_enforce) 911 if (is_enforce)