diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-03 22:13:08 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-03 22:13:08 +0100 |
commit | 79e2598c48ad7e41d523f62368454c7d74f48268 (patch) | |
tree | b061ea33e433dcd509a99dc9726251f2e0f785e5 /loginutils | |
parent | 2b288236e80938d29324072a823f46861bd07cd3 (diff) | |
download | busybox-w32-79e2598c48ad7e41d523f62368454c7d74f48268.tar.gz busybox-w32-79e2598c48ad7e41d523f62368454c7d74f48268.tar.bz2 busybox-w32-79e2598c48ad7e41d523f62368454c7d74f48268.zip |
su: expand help; simplify passing of -c CMD to run_shell()
Also, added a comment about bug 9401 (TIOCSTI input injection).
function old new delta
packed_usage 30909 30932 +23
su_main 470 487 +17
sulogin_main 260 258 -2
run_applet_and_exit 681 678 -3
run_shell 166 126 -40
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'loginutils')
-rw-r--r-- | loginutils/login.c | 2 | ||||
-rw-r--r-- | loginutils/su.c | 33 | ||||
-rw-r--r-- | loginutils/sulogin.c | 2 |
3 files changed, 31 insertions, 6 deletions
diff --git a/loginutils/login.c b/loginutils/login.c index 94b6c45db..52abc1886 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -618,7 +618,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
618 | signal(SIGINT, SIG_DFL); | 618 | signal(SIGINT, SIG_DFL); |
619 | 619 | ||
620 | /* Exec login shell with no additional parameters */ | 620 | /* Exec login shell with no additional parameters */ |
621 | run_shell(pw->pw_shell, 1, NULL, NULL); | 621 | run_shell(pw->pw_shell, 1, NULL); |
622 | 622 | ||
623 | /* return EXIT_FAILURE; - not reached */ | 623 | /* return EXIT_FAILURE; - not reached */ |
624 | } | 624 | } |
diff --git a/loginutils/su.c b/loginutils/su.c index 3c0e8c100..24ffbde86 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -31,10 +31,10 @@ | |||
31 | //kbuild:lib-$(CONFIG_SU) += su.o | 31 | //kbuild:lib-$(CONFIG_SU) += su.o |
32 | 32 | ||
33 | //usage:#define su_trivial_usage | 33 | //usage:#define su_trivial_usage |
34 | //usage: "[OPTIONS] [-] [USER]" | 34 | //usage: "[-lmp] [-] [-s SH] [USER [SCRIPT ARGS / -c 'CMD' ARG0 ARGS]]" |
35 | //usage:#define su_full_usage "\n\n" | 35 | //usage:#define su_full_usage "\n\n" |
36 | //usage: "Run shell under USER (by default, root)\n" | 36 | //usage: "Run shell under USER (by default, root)\n" |
37 | //usage: "\n -,-l Clear environment, run shell as login shell" | 37 | //usage: "\n -,-l Clear environment, go to home dir, run shell as login shell" |
38 | //usage: "\n -p,-m Do not set new $HOME, $SHELL, $USER, $LOGNAME" | 38 | //usage: "\n -p,-m Do not set new $HOME, $SHELL, $USER, $LOGNAME" |
39 | //usage: "\n -c CMD Command to pass to 'sh -c'" | 39 | //usage: "\n -c CMD Command to pass to 'sh -c'" |
40 | //usage: "\n -s SH Shell to use instead of user's default" | 40 | //usage: "\n -s SH Shell to use instead of user's default" |
@@ -81,8 +81,12 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
81 | #endif | 81 | #endif |
82 | const char *old_user; | 82 | const char *old_user; |
83 | 83 | ||
84 | /* Note: we don't use "'+': stop at first non-option" idiom here. | ||
85 | * For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing: | ||
86 | * ARGS starting with dash will be treated as su options, | ||
87 | * not passed to shell. (Tested on util-linux 2.28). | ||
88 | */ | ||
84 | flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell); | 89 | flags = getopt32(argv, "mplc:s:", &opt_command, &opt_shell); |
85 | //argc -= optind; | ||
86 | argv += optind; | 90 | argv += optind; |
87 | 91 | ||
88 | if (argv[0] && LONE_DASH(argv[0])) { | 92 | if (argv[0] && LONE_DASH(argv[0])) { |
@@ -162,8 +166,29 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
162 | pw); | 166 | pw); |
163 | IF_SELINUX(set_current_security_context(NULL);) | 167 | IF_SELINUX(set_current_security_context(NULL);) |
164 | 168 | ||
169 | if (opt_command) { | ||
170 | *--argv = opt_command; | ||
171 | *--argv = (char*)"-c"; | ||
172 | } | ||
173 | |||
174 | /* A nasty ioctl exists which can stuff data into input queue: | ||
175 | * #include <sys/ioctl.h> | ||
176 | * int main() { | ||
177 | * const char *msg = "echo $UID\n"; | ||
178 | * while (*msg) ioctl(0, TIOCSTI, *msg++); | ||
179 | * return 0; | ||
180 | * } | ||
181 | * With "su USER -c EXPLOIT" run by root, exploit can make root shell | ||
182 | * read as input and execute arbitrary command. | ||
183 | * It's debatable whether we need to protect against this | ||
184 | * (root may hesitate to run unknown scripts interactively). | ||
185 | * | ||
186 | * Some versions of su run -c CMD in a different session: | ||
187 | * ioctl(TIOCSTI) works only on the controlling tty. | ||
188 | */ | ||
189 | |||
165 | /* Never returns */ | 190 | /* Never returns */ |
166 | run_shell(opt_shell, flags & SU_OPT_l, opt_command, (const char**)argv); | 191 | run_shell(opt_shell, flags & SU_OPT_l, (const char**)argv); |
167 | 192 | ||
168 | /* return EXIT_FAILURE; - not reached */ | 193 | /* return EXIT_FAILURE; - not reached */ |
169 | } | 194 | } |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 6befea933..2e32e2bbd 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -89,5 +89,5 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
89 | shell = pwd->pw_shell; | 89 | shell = pwd->pw_shell; |
90 | 90 | ||
91 | /* Exec login shell with no additional parameters. Never returns. */ | 91 | /* Exec login shell with no additional parameters. Never returns. */ |
92 | run_shell(shell, 1, NULL, NULL); | 92 | run_shell(shell, 1, NULL); |
93 | } | 93 | } |