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/minijail0.c b/minijail0.c
index 82f67c1..4987001 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -12,6 +12,7 @@
 #include "libminijail.h"
 #include "libsyscalls.h"
 
+#include "elfparse.h"
 #include "util.h"
 
 static void set_user(struct minijail *j, const char *arg)
@@ -224,6 +225,7 @@
 	char *dl_mesg = NULL;
 	int exit_immediately = 0;
 	int consumed = parse_args(j, argc, argv, &exit_immediately);
+	ElfType elftype = ELFERROR;
 	argc -= consumed;
 	argv += consumed;
 	/* Check that we can access the target program. */
@@ -232,13 +234,30 @@
 		        argv[0]);
 		return 1;
 	}
-	/* Check that we can dlopen() libminijailpreload.so. */
-	if (!dlopen(PRELOADPATH, RTLD_LAZY | RTLD_LOCAL)) {
-		dl_mesg = dlerror();
-		fprintf(stderr, "dlopen(): %s\n", dl_mesg);
+	/* Check if target is statically or dynamically linked. */
+	elftype = get_elf_linkage(argv[0]);
+	if (elftype == ELFSTATIC) {
+		/* Target binary is static. */
+		minijail_run_static(j, argv[0], argv);
+	} else if (elftype == ELFDYNAMIC) {
+		/*
+		 * Target binary is dynamically linked so we can
+		 * inject libminijailpreload.so into it.
+		 */
+
+		/* Check that we can dlopen() libminijailpreload.so. */
+		if (!dlopen(PRELOADPATH, RTLD_LAZY | RTLD_LOCAL)) {
+			    dl_mesg = dlerror();
+			    fprintf(stderr, "dlopen(): %s\n", dl_mesg);
+			    return 1;
+		}
+		minijail_run(j, argv[0], argv);
+	} else {
+		fprintf(stderr, "Target program '%s' is not an ELF executable.\n",
+		        argv[0]);
 		return 1;
 	}
-	minijail_run(j, argv[0], argv);
+
 	if (exit_immediately) {
 		info("not running init loop, exiting immediately");
 		return 0;