diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2022-04-30 16:04:47 -0700 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2022-04-30 16:04:47 -0700 |
commit | eb0f1df722d5e760137a0dd85fee8e78c95ee68f (patch) | |
tree | 1ddbb73ecd65ccf72d2e0efeb1aa72a0061d4cb9 | |
parent | 9a9579181897a62dc107b121f139a319d7e297fa (diff) | |
download | libcap-eb0f1df722d5e760137a0dd85fee8e78c95ee68f.tar.gz |
Prevent 'capsh --user=xxx --' from generating a bash error.
This change adds support to capsh for the --noenv argument, which
will restore pre-libcap-2.65 behavior to capsh. The change we're
making here, however, is that capsh will now set the USER and HOME
environment variables when the command line contains --user=xxx.
The issue this addresses is described here:
https://bugzilla.kernel.org/show_bug.cgi?id=215926
This has been annoying me for long enough, and I want to clean up
the article:
https://sites.google.com/site/fullycapable/inheriting-privilege
to not pepper "--norc" in distracting places.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | doc/capsh.1 | 6 | ||||
-rw-r--r-- | progs/capsh.c | 19 |
2 files changed, 24 insertions, 1 deletions
diff --git a/doc/capsh.1 b/doc/capsh.1 index aafe3fb..4f3aaae 100644 --- a/doc/capsh.1 +++ b/doc/capsh.1 @@ -329,6 +329,12 @@ Removes the specified ambient capability from the running process. .B \-\-noamb Drops all ambient capabilities from the running process. .TP +.B \-\-noenv +Suppresses overriding of the HOME and USER environment variables when +a subsequent +.B \-\-user +argument is processed. +.TP .B \-\-quiet This argument is ignored unless it is the first one. If present, it suppresses the capsh runtime check to confirm the running libcap is diff --git a/progs/capsh.c b/progs/capsh.c index 4f568c3..f753291 100644 --- a/progs/capsh.c +++ b/progs/capsh.c @@ -509,7 +509,7 @@ int main(int argc, char *argv[], char *envp[]) { pid_t child = 0; unsigned i; - int strict = 0, quiet_start = 0; + int strict = 0, quiet_start = 0, dont_set_env = 0; const char *shell = SHELL; for (i=1; i<argc; ++i) { @@ -558,6 +558,8 @@ int main(int argc, char *argv[], char *envp[]) perror("failed to reset ambient set"); exit(1); } + } else if (!strcmp("--noenv", argv[i])) { + dont_set_env = 1; } else if (!strncmp("--inh=", argv[i], 6)) { cap_t all, raised_for_setpcap; char *text; @@ -912,6 +914,20 @@ int main(int argc, char *argv[], char *envp[]) pwd->pw_uid, user, strerror(errno)); exit(1); } + if (!dont_set_env) { + /* + * not setting this confuses bash at start up, but use + * --noenv to preserve the HOME etc values instead. + */ + if (setenv("HOME", pwd->pw_dir, 1) != 0) { + perror("unable to set HOME"); + exit(1); + } + if (setenv("USER", user, 1) != 0) { + perror("unable to set USER"); + exit(1); + } + } } else if (!strncmp("--decode=", argv[i], 9)) { unsigned long long value; unsigned cap; @@ -1170,6 +1186,7 @@ int main(int argc, char *argv[], char *envp[]) " --modes list libcap named modes\n" " --no-new-privs set sticky process privilege limiter\n" " --noamb reset (drop) all ambient capabilities\n" + " --noenv no fixup of env vars (for --user)\n" " --print display capability relevant state\n" " --quiet if first argument skip max cap check\n" " --secbits=<n> write a new value for securebits\n" |