minijail: Restore original value of LD_PRELOAD after fork.

This CL restores the original value of LD_PRELOAD in the process that
calls minijain_run. This prevents any subsequent process, which is not
created by minijail_run, from preloading libminijalpreload.so.

BUG=chromium-os:19732
TEST=Examined the environment of calling process after minijain_run returns.

Change-Id: I578e4c46c72eb549fa59353ab1a25f0160077a03
Reviewed-on: http://gerrit.chromium.org/gerrit/6788
Reviewed-by: Elly Jones <ellyjones@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 3c5ec58..2afa236 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -303,7 +303,7 @@
     return -E2BIG;
   }
 
-  oldenv = getenv("LD_PRELOAD") ? : "";
+  oldenv = getenv(kLdPreloadEnvVar) ? : "";
   newenv = malloc(strlen(oldenv) + 2 + strlen(PRELOADPATH));
   if (!newenv) {
     free(envbuf);
@@ -314,7 +314,7 @@
   sprintf(newenv, "%s%s%s", oldenv, strlen(oldenv) ? " " : "", PRELOADPATH);
 
   /* setenv() makes a copy of the string we give it */
-  setenv("LD_PRELOAD", newenv, 1);
+  setenv(kLdPreloadEnvVar, newenv, 1);
   setenv(kCommandEnvVar, envbuf, 1);
   free(newenv);
   free(envbuf);
@@ -323,16 +323,39 @@
 
 int minijail_run(struct minijail *j, const char *filename, char *const argv[]) {
   unsigned int pidns = j->flags.pids ? CLONE_NEWPID : 0;
+  char *oldenv, *oldenv_copy = NULL;
   pid_t r;
+
+  oldenv = getenv(kLdPreloadEnvVar);
+  if (oldenv) {
+    oldenv_copy = strdup(oldenv);
+    if (!oldenv_copy)
+      return -ENOMEM;
+  }
+
   r = move_commands_to_env(j);
-  if (r)
+  if (r) {
+    /* No environment variable is modified if move_commands_to_env returns
+     * a non-zero value. */
+    free(oldenv_copy);
     return r;
+  }
 
   r = syscall(SYS_clone, pidns | SIGCHLD, NULL);
   if (r > 0) {
+    if (oldenv_copy) {
+      setenv(kLdPreloadEnvVar, oldenv_copy, 1);
+      free(oldenv_copy);
+    } else {
+      unsetenv(kLdPreloadEnvVar);
+    }
+    unsetenv(kCommandEnvVar);
     j->initpid = r;
     return 0;
   }
+
+  free(oldenv_copy);
+
   if (r < 0)
     return r;
 
@@ -384,4 +407,3 @@
 void minijail_destroy(struct minijail *j) {
   free(j);
 }
-