Allow minijail to run statically linked targets

minijail will now detect static targets and sandbox them

BUG:chromium:355109
TEST=Tested with autotest security_Minijail0 on arm and x64

Change-Id: I4c38f652207c5c50158449f952b14e9402e17751
Reviewed-on: https://chromium-review.googlesource.com/203013
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Tested-by: Lee Campbell <leecam@chromium.org>
Commit-Queue: Lee Campbell <leecam@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 90fd4a7..d4b9d16 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -1076,7 +1076,7 @@
 
 	if (child_pid < 0) {
 		free(oldenv_copy);
-		return child_pid;
+		die("failed to fork child");
 	}
 
 	if (child_pid) {
@@ -1195,6 +1195,56 @@
 	_exit(execve(filename, argv, environ));
 }
 
+int API minijail_run_static(struct minijail *j, const char *filename,
+			    char *const argv[])
+{
+	pid_t child_pid;
+	int pid_namespace = j->flags.pids;
+
+	if (j->flags.caps)
+		die("caps not supported with static targets");
+
+	if (pid_namespace)
+		child_pid = syscall(SYS_clone, CLONE_NEWPID | SIGCHLD, NULL);
+	else
+		child_pid = fork();
+
+	if (child_pid < 0) {
+		die("failed to fork child");
+	}
+	if (child_pid > 0 ) {
+		j->initpid = child_pid;
+		return 0;
+	}
+
+	/*
+	 * We can now drop this child into the sandbox
+	 * then execve the target.
+	 */
+
+	j->flags.pids = 0;
+	minijail_enter(j);
+
+	if (pid_namespace) {
+		/*
+		 * pid namespace: this process will become init inside the new
+		 * namespace, so fork off a child to actually run the program
+		 * (we don't want all programs we might exec to have to know
+		 * how to be init).
+		 *
+		 * If we're multithreaded, we'll probably deadlock here. See
+		 * WARNING above.
+		 */
+		child_pid = fork();
+		if (child_pid < 0)
+			_exit(child_pid);
+		else if (child_pid > 0)
+			init(child_pid);	/* never returns */
+	}
+
+	_exit(execve(filename, argv, environ));
+}
+
 int API minijail_kill(struct minijail *j)
 {
 	int st;