diff options
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r-- | security/tomoyo/domain.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index a1fc6b5f6125..860390ee1fbe 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -102,6 +102,15 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, | |||
102 | new_entry->cond = tomoyo_get_condition(param); | 102 | new_entry->cond = tomoyo_get_condition(param); |
103 | if (!new_entry->cond) | 103 | if (!new_entry->cond) |
104 | return -EINVAL; | 104 | return -EINVAL; |
105 | /* | ||
106 | * Domain transition preference is allowed for only | ||
107 | * "file execute" entries. | ||
108 | */ | ||
109 | if (new_entry->cond->transit && | ||
110 | !(new_entry->type == TOMOYO_TYPE_PATH_ACL && | ||
111 | container_of(new_entry, struct tomoyo_path_acl, head) | ||
112 | ->perm == 1 << TOMOYO_TYPE_EXECUTE)) | ||
113 | goto out; | ||
105 | } | 114 | } |
106 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 115 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) |
107 | goto out; | 116 | goto out; |
@@ -707,8 +716,7 @@ retry: | |||
707 | } | 716 | } |
708 | 717 | ||
709 | /* Check execute permission. */ | 718 | /* Check execute permission. */ |
710 | retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, | 719 | retval = tomoyo_execute_permission(&ee->r, candidate); |
711 | candidate); | ||
712 | if (retval == TOMOYO_RETRY_REQUEST) | 720 | if (retval == TOMOYO_RETRY_REQUEST) |
713 | goto retry; | 721 | goto retry; |
714 | if (retval < 0) | 722 | if (retval < 0) |
@@ -722,10 +730,45 @@ retry: | |||
722 | if (ee->r.param.path.matched_path) | 730 | if (ee->r.param.path.matched_path) |
723 | candidate = ee->r.param.path.matched_path; | 731 | candidate = ee->r.param.path.matched_path; |
724 | 732 | ||
725 | /* Calculate domain to transit to. */ | 733 | /* |
734 | * Check for domain transition preference if "file execute" matched. | ||
735 | * If preference is given, make do_execve() fail if domain transition | ||
736 | * has failed, for domain transition preference should be used with | ||
737 | * destination domain defined. | ||
738 | */ | ||
739 | if (ee->transition) { | ||
740 | const char *domainname = ee->transition->name; | ||
741 | reject_on_transition_failure = true; | ||
742 | if (!strcmp(domainname, "keep")) | ||
743 | goto force_keep_domain; | ||
744 | if (!strcmp(domainname, "child")) | ||
745 | goto force_child_domain; | ||
746 | if (!strcmp(domainname, "reset")) | ||
747 | goto force_reset_domain; | ||
748 | if (!strcmp(domainname, "initialize")) | ||
749 | goto force_initialize_domain; | ||
750 | if (!strcmp(domainname, "parent")) { | ||
751 | char *cp; | ||
752 | strncpy(ee->tmp, old_domain->domainname->name, | ||
753 | TOMOYO_EXEC_TMPSIZE - 1); | ||
754 | cp = strrchr(ee->tmp, ' '); | ||
755 | if (cp) | ||
756 | *cp = '\0'; | ||
757 | } else if (*domainname == '<') | ||
758 | strncpy(ee->tmp, domainname, TOMOYO_EXEC_TMPSIZE - 1); | ||
759 | else | ||
760 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", | ||
761 | old_domain->domainname->name, domainname); | ||
762 | goto force_jump_domain; | ||
763 | } | ||
764 | /* | ||
765 | * No domain transition preference specified. | ||
766 | * Calculate domain to transit to. | ||
767 | */ | ||
726 | switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, | 768 | switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, |
727 | candidate)) { | 769 | candidate)) { |
728 | case TOMOYO_TRANSITION_CONTROL_RESET: | 770 | case TOMOYO_TRANSITION_CONTROL_RESET: |
771 | force_reset_domain: | ||
729 | /* Transit to the root of specified namespace. */ | 772 | /* Transit to the root of specified namespace. */ |
730 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", | 773 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", |
731 | candidate->name); | 774 | candidate->name); |
@@ -736,11 +779,13 @@ retry: | |||
736 | reject_on_transition_failure = true; | 779 | reject_on_transition_failure = true; |
737 | break; | 780 | break; |
738 | case TOMOYO_TRANSITION_CONTROL_INITIALIZE: | 781 | case TOMOYO_TRANSITION_CONTROL_INITIALIZE: |
782 | force_initialize_domain: | ||
739 | /* Transit to the child of current namespace's root. */ | 783 | /* Transit to the child of current namespace's root. */ |
740 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", | 784 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", |
741 | old_domain->ns->name, candidate->name); | 785 | old_domain->ns->name, candidate->name); |
742 | break; | 786 | break; |
743 | case TOMOYO_TRANSITION_CONTROL_KEEP: | 787 | case TOMOYO_TRANSITION_CONTROL_KEEP: |
788 | force_keep_domain: | ||
744 | /* Keep current domain. */ | 789 | /* Keep current domain. */ |
745 | domain = old_domain; | 790 | domain = old_domain; |
746 | break; | 791 | break; |
@@ -756,11 +801,13 @@ retry: | |||
756 | domain = old_domain; | 801 | domain = old_domain; |
757 | break; | 802 | break; |
758 | } | 803 | } |
804 | force_child_domain: | ||
759 | /* Normal domain transition. */ | 805 | /* Normal domain transition. */ |
760 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", | 806 | snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", |
761 | old_domain->domainname->name, candidate->name); | 807 | old_domain->domainname->name, candidate->name); |
762 | break; | 808 | break; |
763 | } | 809 | } |
810 | force_jump_domain: | ||
764 | if (!domain) | 811 | if (!domain) |
765 | domain = tomoyo_assign_domain(ee->tmp, true); | 812 | domain = tomoyo_assign_domain(ee->tmp, true); |
766 | if (domain) | 813 | if (domain) |