virt-login-shell: fully reset container environment

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>
This commit is contained in:
Daniel P. Berrange 2016-04-12 16:52:58 +01:00
parent 1ebe6f2434
commit ee877b8710

View 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);