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.c53
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:
771force_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:
782force_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:
788force_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 }
804force_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 }
810force_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)