diff options
Diffstat (limited to 'security/tomoyo/domain.c')
-rw-r--r-- | security/tomoyo/domain.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 565249c42e39..878d0206f43e 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -575,23 +575,27 @@ out: */ int tomoyo_find_next_domain(struct linux_binprm *bprm) { - struct tomoyo_request_info r; - char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); struct tomoyo_domain_info *old_domain = tomoyo_domain(); struct tomoyo_domain_info *domain = NULL; const char *original_name = bprm->filename; - u8 mode; - bool is_enforce; int retval = -ENOMEM; bool need_kfree = false; bool reject_on_transition_failure = false; struct tomoyo_path_info rn = { }; /* real name */ - - mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); - is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); - if (!tmp) - goto out; - + struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS); + if (!ee) + return -ENOMEM; + ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); + if (!ee->tmp) { + kfree(ee); + return -ENOMEM; + } + /* ee->dump->data is allocated by tomoyo_dump_page(). */ + tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE); + ee->r.ee = ee; + ee->bprm = bprm; + ee->r.obj = &ee->obj; + ee->obj.path1 = bprm->file->f_path; retry: if (need_kfree) { kfree(rn.name); @@ -625,7 +629,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) } /* Check execute permission. */ - retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn); + retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn); if (retval == TOMOYO_RETRY_REQUEST) goto retry; if (retval < 0) @@ -636,12 +640,12 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) * wildcard) rather than the pathname passed to execve() * (which never contains wildcard). */ - if (r.param.path.matched_path) { + if (ee->r.param.path.matched_path) { if (need_kfree) kfree(rn.name); need_kfree = false; /* This is OK because it is read only. */ - rn = *r.param.path.matched_path; + rn = *ee->r.param.path.matched_path; } /* Calculate domain to transit to. */ @@ -649,7 +653,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) &rn)) { case TOMOYO_TRANSITION_CONTROL_RESET: /* Transit to the root of specified namespace. */ - snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); + snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); /* * Make do_execve() fail if domain transition across namespaces * has failed. @@ -658,7 +662,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) break; case TOMOYO_TRANSITION_CONTROL_INITIALIZE: /* Transit to the child of current namespace's root. */ - snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", + snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", old_domain->ns->name, rn.name); break; case TOMOYO_TRANSITION_CONTROL_KEEP: @@ -677,29 +681,30 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) domain = old_domain; } else { /* Normal domain transition. */ - snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", + snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", old_domain->domainname->name, rn.name); } break; } if (!domain) - domain = tomoyo_assign_domain(tmp, true); + domain = tomoyo_assign_domain(ee->tmp, true); if (domain) retval = 0; else if (reject_on_transition_failure) { - printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", tmp); + printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", + ee->tmp); retval = -ENOMEM; - } else if (r.mode == TOMOYO_CONFIG_ENFORCING) + } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING) retval = -ENOMEM; else { retval = 0; if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) { old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true; - r.granted = false; - tomoyo_write_log(&r, "%s", tomoyo_dif + ee->r.granted = false; + tomoyo_write_log(&ee->r, "%s", tomoyo_dif [TOMOYO_DIF_TRANSITION_FAILED]); printk(KERN_WARNING - "ERROR: Domain '%s' not defined.\n", tmp); + "ERROR: Domain '%s' not defined.\n", ee->tmp); } } out: @@ -710,7 +715,9 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) bprm->cred->security = domain; if (need_kfree) kfree(rn.name); - kfree(tmp); + kfree(ee->tmp); + kfree(ee->dump.data); + kfree(ee); return retval; } |