Exit if unable to dlopen() libminijailpreload.so.

BUG=chromium:204504
TEST=Unit tests, Minijail autotests.
TEST=Rename libminijailpreload.so, run 'minijail0 -- /usr/bin/id', see error.

Change-Id: I3978775662a7710b89f274e7ed7c265d9b923ca2
Reviewed-on: https://chromium-review.googlesource.com/182103
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Commit-Queue: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/Makefile b/Makefile
index c86a647..be4f8e4 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 
 minijail0 : libsyscalls.gen.o libminijail.o syscall_filter.o \
 		signal.o bpf.o util.o minijail0.c
-	$(CC) $(CFLAGS) -o $@ $^ -lcap
+	$(CC) $(CFLAGS) -o $@ $^ -lcap -ldl
 
 libminijail.so : libminijail.o syscall_filter.o signal.o bpf.o util.o \
 		libsyscalls.gen.o
diff --git a/minijail0.c b/minijail0.c
index 6d9233c..e857ea4 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -3,6 +3,7 @@
  * found in the LICENSE file.
  */
 
+#include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -203,15 +204,23 @@
 int main(int argc, char *argv[])
 {
 	struct minijail *j = minijail_new();
+	char *dl_mesg = NULL;
 	int exit_immediately = 0;
 	int consumed = parse_args(j, argc, argv, &exit_immediately);
 	argc -= consumed;
 	argv += consumed;
+	/* Check that we can access the target program. */
 	if (access(argv[0], X_OK)) {
 		fprintf(stderr, "Target program '%s' not accessible\n",
 		        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);
+		return 1;
+	}
 	minijail_run(j, argv[0], argv);
 	if (exit_immediately) {
 		info("not running init loop, exiting immediately");