aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/domain.c56
1 files changed, 22 insertions, 34 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 498fea732f48..a1fc6b5f6125 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -664,9 +664,9 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
664 struct tomoyo_domain_info *domain = NULL; 664 struct tomoyo_domain_info *domain = NULL;
665 const char *original_name = bprm->filename; 665 const char *original_name = bprm->filename;
666 int retval = -ENOMEM; 666 int retval = -ENOMEM;
667 bool need_kfree = false;
668 bool reject_on_transition_failure = false; 667 bool reject_on_transition_failure = false;
669 struct tomoyo_path_info rn = { }; /* real name */ 668 const struct tomoyo_path_info *candidate;
669 struct tomoyo_path_info exename;
670 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS); 670 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
671 671
672 if (!ee) 672 if (!ee)
@@ -682,40 +682,33 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
682 ee->bprm = bprm; 682 ee->bprm = bprm;
683 ee->r.obj = &ee->obj; 683 ee->r.obj = &ee->obj;
684 ee->obj.path1 = bprm->file->f_path; 684 ee->obj.path1 = bprm->file->f_path;
685 retry:
686 if (need_kfree) {
687 kfree(rn.name);
688 need_kfree = false;
689 }
690 /* Get symlink's pathname of program. */ 685 /* Get symlink's pathname of program. */
691 retval = -ENOENT; 686 retval = -ENOENT;
692 rn.name = tomoyo_realpath_nofollow(original_name); 687 exename.name = tomoyo_realpath_nofollow(original_name);
693 if (!rn.name) 688 if (!exename.name)
694 goto out; 689 goto out;
695 tomoyo_fill_path_info(&rn); 690 tomoyo_fill_path_info(&exename);
696 need_kfree = true; 691retry:
697
698 /* Check 'aggregator' directive. */ 692 /* Check 'aggregator' directive. */
699 { 693 {
700 struct tomoyo_aggregator *ptr; 694 struct tomoyo_aggregator *ptr;
701 struct list_head *list = 695 struct list_head *list =
702 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 696 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
703 /* Check 'aggregator' directive. */ 697 /* Check 'aggregator' directive. */
698 candidate = &exename;
704 list_for_each_entry_rcu(ptr, list, head.list) { 699 list_for_each_entry_rcu(ptr, list, head.list) {
705 if (ptr->head.is_deleted || 700 if (ptr->head.is_deleted ||
706 !tomoyo_path_matches_pattern(&rn, 701 !tomoyo_path_matches_pattern(&exename,
707 ptr->original_name)) 702 ptr->original_name))
708 continue; 703 continue;
709 kfree(rn.name); 704 candidate = ptr->aggregated_name;
710 need_kfree = false;
711 /* This is OK because it is read only. */
712 rn = *ptr->aggregated_name;
713 break; 705 break;
714 } 706 }
715 } 707 }
716 708
717 /* Check execute permission. */ 709 /* Check execute permission. */
718 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn); 710 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE,
711 candidate);
719 if (retval == TOMOYO_RETRY_REQUEST) 712 if (retval == TOMOYO_RETRY_REQUEST)
720 goto retry; 713 goto retry;
721 if (retval < 0) 714 if (retval < 0)
@@ -726,20 +719,16 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
726 * wildcard) rather than the pathname passed to execve() 719 * wildcard) rather than the pathname passed to execve()
727 * (which never contains wildcard). 720 * (which never contains wildcard).
728 */ 721 */
729 if (ee->r.param.path.matched_path) { 722 if (ee->r.param.path.matched_path)
730 if (need_kfree) 723 candidate = ee->r.param.path.matched_path;
731 kfree(rn.name);
732 need_kfree = false;
733 /* This is OK because it is read only. */
734 rn = *ee->r.param.path.matched_path;
735 }
736 724
737 /* Calculate domain to transit to. */ 725 /* Calculate domain to transit to. */
738 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, 726 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
739 &rn)) { 727 candidate)) {
740 case TOMOYO_TRANSITION_CONTROL_RESET: 728 case TOMOYO_TRANSITION_CONTROL_RESET:
741 /* Transit to the root of specified namespace. */ 729 /* Transit to the root of specified namespace. */
742 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); 730 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
731 candidate->name);
743 /* 732 /*
744 * Make do_execve() fail if domain transition across namespaces 733 * Make do_execve() fail if domain transition across namespaces
745 * has failed. 734 * has failed.
@@ -749,7 +738,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
749 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 738 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
750 /* Transit to the child of current namespace's root. */ 739 /* Transit to the child of current namespace's root. */
751 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 740 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
752 old_domain->ns->name, rn.name); 741 old_domain->ns->name, candidate->name);
753 break; 742 break;
754 case TOMOYO_TRANSITION_CONTROL_KEEP: 743 case TOMOYO_TRANSITION_CONTROL_KEEP:
755 /* Keep current domain. */ 744 /* Keep current domain. */
@@ -765,11 +754,11 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
765 * before /sbin/init. 754 * before /sbin/init.
766 */ 755 */
767 domain = old_domain; 756 domain = old_domain;
768 } else { 757 break;
769 /* Normal domain transition. */
770 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
771 old_domain->domainname->name, rn.name);
772 } 758 }
759 /* Normal domain transition. */
760 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
761 old_domain->domainname->name, candidate->name);
773 break; 762 break;
774 } 763 }
775 if (!domain) 764 if (!domain)
@@ -799,8 +788,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
799 /* Update reference count on "struct tomoyo_domain_info". */ 788 /* Update reference count on "struct tomoyo_domain_info". */
800 atomic_inc(&domain->users); 789 atomic_inc(&domain->users);
801 bprm->cred->security = domain; 790 bprm->cred->security = domain;
802 if (need_kfree) 791 kfree(exename.name);
803 kfree(rn.name);
804 if (!retval) { 792 if (!retval) {
805 ee->r.domain = domain; 793 ee->r.domain = domain;
806 retval = tomoyo_environ(ee); 794 retval = tomoyo_environ(ee);