aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-06 05:26:51 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-06 05:26:51 +0000
commit52816302299854ba1644fce98b5d19db526e6c29 (patch)
tree7ddd6080d6a9fca759227b184dcc445d5376a075
parent6bef3d1d2216234454875052220ca0f477a820b4 (diff)
downloadbusybox-w32-52816302299854ba1644fce98b5d19db526e6c29.tar.gz
busybox-w32-52816302299854ba1644fce98b5d19db526e6c29.tar.bz2
busybox-w32-52816302299854ba1644fce98b5d19db526e6c29.zip
login: clear dangerous environment variables if started by non-root
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/login.c26
-rw-r--r--loginutils/login.c14
-rw-r--r--loginutils/sulogin.c25
4 files changed, 42 insertions, 25 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 77c678cee..f79d80d7f 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -623,6 +623,8 @@ enum {
623#endif 623#endif
624void bb_daemonize_or_rexec(int flags, char **argv); 624void bb_daemonize_or_rexec(int flags, char **argv);
625void bb_sanitize_stdio(void); 625void bb_sanitize_stdio(void);
626/* Clear dangerous stuff, set PATH */
627void sanitize_env_for_suid(void);
626 628
627 629
628extern const char *opt_complementary; 630extern const char *opt_complementary;
diff --git a/libbb/login.c b/libbb/login.c
index 308e1bfed..1af3165b9 100644
--- a/libbb/login.c
+++ b/libbb/login.c
@@ -99,3 +99,29 @@ void print_login_prompt(void)
99 fputs(LOGIN, stdout); 99 fputs(LOGIN, stdout);
100 fflush(stdout); 100 fflush(stdout);
101} 101}
102
103/* Clear dangerous stuff, set PATH */
104static const char forbid[] ALIGN1 =
105 "ENV" "\0"
106 "BASH_ENV" "\0"
107 "HOME" "\0"
108 "IFS" "\0"
109 "SHELL" "\0"
110 "LD_LIBRARY_PATH" "\0"
111 "LD_PRELOAD" "\0"
112 "LD_TRACE_LOADED_OBJECTS" "\0"
113 "LD_BIND_NOW" "\0"
114 "LD_AOUT_LIBRARY_PATH" "\0"
115 "LD_AOUT_PRELOAD" "\0"
116 "LD_NOWARN" "\0"
117 "LD_KEEPDIR" "\0";
118
119void sanitize_env_for_suid(void)
120{
121 const char *p = forbid;
122 do {
123 unsetenv(p);
124 p += strlen(p) + 1;
125 } while (*p);
126 putenv((char*)bb_PATH_root_path);
127}
diff --git a/loginutils/login.c b/loginutils/login.c
index bddc0f533..c05edde36 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -201,7 +201,7 @@ static void motd(void)
201 int fd; 201 int fd;
202 202
203 fd = open(bb_path_motd_file, O_RDONLY); 203 fd = open(bb_path_motd_file, O_RDONLY);
204 if (fd) { 204 if (fd >= 0) {
205 fflush(stdout); 205 fflush(stdout);
206 bb_copyfd_eof(fd, STDOUT_FILENO); 206 bb_copyfd_eof(fd, STDOUT_FILENO);
207 close(fd); 207 close(fd);
@@ -216,6 +216,10 @@ static void alarm_handler(int sig ATTRIBUTE_UNUSED)
216 ndelay_on(1); 216 ndelay_on(1);
217 ndelay_on(2); 217 ndelay_on(2);
218 printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT); 218 printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);
219 /* unix API is brain damaged regarding O_NONBLOCK,
220 * we should undo it, or else we can affect other processes */
221 ndelay_off(1);
222 ndelay_off(2);
219 exit(EXIT_SUCCESS); 223 exit(EXIT_SUCCESS);
220} 224}
221 225
@@ -254,6 +258,11 @@ int login_main(int argc, char **argv)
254 * and any extra open fd's are closed. 258 * and any extra open fd's are closed.
255 * (The name of the function is misleading. Not daemonizing here.) */ 259 * (The name of the function is misleading. Not daemonizing here.) */
256 bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); 260 bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL);
261 /* More of suid paranoia if called by non-root */
262 if (!amroot) {
263 /* Clear dangerous stuff, set PATH */
264 sanitize_env_for_suid();
265 }
257 266
258 opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); 267 opt = getopt32(argv, "f:h:p", &opt_user, &opt_host);
259 if (opt & LOGIN_OPT_f) { 268 if (opt & LOGIN_OPT_f) {
@@ -411,7 +420,8 @@ int login_main(int argc, char **argv)
411 fchown(0, pw->pw_uid, pw->pw_gid); 420 fchown(0, pw->pw_uid, pw->pw_gid);
412 fchmod(0, 0600); 421 fchmod(0, 0600);
413 422
414 if (ENABLE_LOGIN_SCRIPTS) { 423 /* We trust environment only if we run by root */
424 if (ENABLE_LOGIN_SCRIPTS && amroot) {
415 char *t_argv[2]; 425 char *t_argv[2];
416 426
417 t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT"); 427 t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index f1545b78f..af457ef1e 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -9,22 +9,6 @@
9 9
10#include "libbb.h" 10#include "libbb.h"
11 11
12static const char forbid[] ALIGN1 =
13 "ENV" "\0"
14 "BASH_ENV" "\0"
15 "HOME" "\0"
16 "IFS" "\0"
17 "PATH" "\0"
18 "SHELL" "\0"
19 "LD_LIBRARY_PATH" "\0"
20 "LD_PRELOAD" "\0"
21 "LD_TRACE_LOADED_OBJECTS" "\0"
22 "LD_BIND_NOW" "\0"
23 "LD_AOUT_LIBRARY_PATH" "\0"
24 "LD_AOUT_PRELOAD" "\0"
25 "LD_NOWARN" "\0"
26 "LD_KEEPDIR" "\0";
27
28//static void catchalarm(int ATTRIBUTE_UNUSED junk) 12//static void catchalarm(int ATTRIBUTE_UNUSED junk)
29//{ 13//{
30// exit(EXIT_FAILURE); 14// exit(EXIT_FAILURE);
@@ -37,7 +21,6 @@ int sulogin_main(int argc, char **argv)
37 char *cp; 21 char *cp;
38 int timeout = 0; 22 int timeout = 0;
39 char *timeout_arg; 23 char *timeout_arg;
40 const char *p;
41 struct passwd *pwd; 24 struct passwd *pwd;
42 const char *shell; 25 const char *shell;
43#if ENABLE_FEATURE_SHADOWPASSWDS 26#if ENABLE_FEATURE_SHADOWPASSWDS
@@ -66,12 +49,8 @@ int sulogin_main(int argc, char **argv)
66 bb_error_msg_and_die("not a tty"); 49 bb_error_msg_and_die("not a tty");
67 } 50 }
68 51
69 /* Clear out anything dangerous from the environment */ 52 /* Clear dangerous stuff, set PATH */
70 p = forbid; 53 sanitize_env_for_suid();
71 do {
72 unsetenv(p);
73 p += strlen(p) + 1;
74 } while (*p);
75 54
76// bb_askpass() already handles this 55// bb_askpass() already handles this
77// signal(SIGALRM, catchalarm); 56// signal(SIGALRM, catchalarm);