TOMOYO: Enable conditional ACL.

Enable conditional ACL by passing object's pointers.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 565249c..878d020 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -575,23 +575,27 @@
  */
 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 @@
 	}
 
 	/* 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 @@
 	 * 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 @@
 				       &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 @@
 		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 @@
 			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 @@
 	bprm->cred->security = domain;
 	if (need_kfree)
 		kfree(rn.name);
-	kfree(tmp);
+	kfree(ee->tmp);
+	kfree(ee->dump.data);
+	kfree(ee);
 	return retval;
 }