]> xenbits.xensource.com Git - libvirt.git/commitdiff
virt-login-shell: fully reset container environment
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 12 Apr 2016 15:52:58 +0000 (16:52 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Jun 2016 10:03:02 +0000 (11:03 +0100)
The virt-login-shell environment will be initialized with
an arbitrary number of environment variables determined
by the SSH daemon and PAM configuration. Most of these are
not relevant inside the container, and at best they are
noise and at worst they'll break apps. For example if
XDG_RUNTIME_DIR is leaked to the container, it'll break
any apps using it, since  the directory it points to is
only visible to the host OS filesystem, not the container
FS.

Use clearenv() to blank out everything and then set known
good values for PATH, SHELL, USER, LOGNAME HOME and TERM.
Everything else is left up to the login shell to initialize.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
tools/virt-login-shell.c

index 59ec801501150ea68c32d8b70de028c34950a255..784008bc569db82103b127f7aa1eaf646902cb91 100644 (file)
@@ -220,6 +220,7 @@ main(int argc, char **argv)
     size_t i;
     const char *cmdstr = NULL;
     char *tmp;
+    char *term = NULL;
     virErrorPtr saved_err = NULL;
 
     struct option opt[] = {
@@ -232,8 +233,6 @@ main(int argc, char **argv)
         return EXIT_CANCELED;
     }
 
-    setenv("PATH", "/bin:/usr/bin", 1);
-
     virSetErrorFunc(NULL, NULL);
     virSetErrorLogPriorityFunc(NULL);
 
@@ -369,6 +368,12 @@ main(int argc, char **argv)
         goto cleanup;
     shargv[0][0] = '-';
 
+    /* We're duping the string because the clearenv()
+     * call will shortly release the pointer we get
+     * back from virGetEnvAllowSUID() right here */
+    if (VIR_STRDUP(term, virGetEnvAllowSUID("TERM")) < 0)
+        goto cleanup;
+
     /* A fork is required to create new process in correct pid namespace.  */
     if ((cpid = virFork()) < 0)
         goto cleanup;
@@ -380,6 +385,16 @@ main(int argc, char **argv)
             tmpfd = i;
             VIR_MASS_CLOSE(tmpfd);
         }
+
+        clearenv();
+        setenv("PATH", "/bin:/usr/bin", 1);
+        setenv("SHELL", shcmd, 1);
+        setenv("USER", name, 1);
+        setenv("LOGNAME", name, 1);
+        setenv("HOME", homedir, 1);
+        if (term)
+            setenv("TERM", term, 1);
+
         if (execv(shcmd, (char *const*) shargv) < 0) {
             virReportSystemError(errno, _("Unable to exec shell %s"),
                                  shcmd);
@@ -404,6 +419,7 @@ main(int argc, char **argv)
         virConnectClose(conn);
     virStringFreeList(shargv);
     VIR_FREE(shcmd);
+    VIR_FREE(term);
     VIR_FREE(name);
     VIR_FREE(homedir);
     VIR_FREE(seclabel);