diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-18 11:08:33 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-18 11:08:33 +0000 |
commit | c9ca0a32745a43eaa6cb6b7b460718de8ccb84f2 (patch) | |
tree | 2b4bdf035b3a3c0436ce823e137d969af4d3a06f | |
parent | 56244736ec7d0a3c338f542204aae83fb0200346 (diff) | |
download | busybox-w32-c9ca0a32745a43eaa6cb6b7b460718de8ccb84f2.tar.gz busybox-w32-c9ca0a32745a43eaa6cb6b7b460718de8ccb84f2.tar.bz2 busybox-w32-c9ca0a32745a43eaa6cb6b7b460718de8ccb84f2.zip |
mount: recognize "dirsync" (closes bug 835)
mount: sanitize environ if called by non-root
*: adjust for slightly different sanitize routine
-rw-r--r-- | include/libbb.h | 4 | ||||
-rw-r--r-- | libbb/login.c | 11 | ||||
-rw-r--r-- | loginutils/login.c | 9 | ||||
-rw-r--r-- | loginutils/sulogin.c | 2 | ||||
-rw-r--r-- | miscutils/crontab.c | 11 | ||||
-rw-r--r-- | networking/nc.c | 17 | ||||
-rw-r--r-- | util-linux/mount.c | 9 |
7 files changed, 37 insertions, 26 deletions
diff --git a/include/libbb.h b/include/libbb.h index 2af89df95..a91eac466 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -684,8 +684,8 @@ enum { | |||
684 | #endif | 684 | #endif |
685 | void bb_daemonize_or_rexec(int flags, char **argv); | 685 | void bb_daemonize_or_rexec(int flags, char **argv); |
686 | void bb_sanitize_stdio(void); | 686 | void bb_sanitize_stdio(void); |
687 | /* Clear dangerous stuff, set PATH */ | 687 | /* Clear dangerous stuff, set PATH. Return 1 if was run by different user. */ |
688 | void sanitize_env_for_suid(void); | 688 | int sanitize_env_if_suid(void); |
689 | 689 | ||
690 | 690 | ||
691 | extern const char *opt_complementary; | 691 | extern const char *opt_complementary; |
diff --git a/libbb/login.c b/libbb/login.c index 1af3165b9..d1f5d6498 100644 --- a/libbb/login.c +++ b/libbb/login.c | |||
@@ -116,12 +116,19 @@ static const char forbid[] ALIGN1 = | |||
116 | "LD_NOWARN" "\0" | 116 | "LD_NOWARN" "\0" |
117 | "LD_KEEPDIR" "\0"; | 117 | "LD_KEEPDIR" "\0"; |
118 | 118 | ||
119 | void sanitize_env_for_suid(void) | 119 | int sanitize_env_if_suid(void) |
120 | { | 120 | { |
121 | const char *p = forbid; | 121 | const char *p; |
122 | |||
123 | if (getuid() == geteuid()) | ||
124 | return 0; | ||
125 | |||
126 | p = forbid; | ||
122 | do { | 127 | do { |
123 | unsetenv(p); | 128 | unsetenv(p); |
124 | p += strlen(p) + 1; | 129 | p += strlen(p) + 1; |
125 | } while (*p); | 130 | } while (*p); |
126 | putenv((char*)bb_PATH_root_path); | 131 | putenv((char*)bb_PATH_root_path); |
132 | |||
133 | return 1; /* we indeed were run by different user! */ | ||
127 | } | 134 | } |
diff --git a/loginutils/login.c b/loginutils/login.c index 55cbfa7cd..a5b6369ff 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -254,20 +254,17 @@ int login_main(int argc, char **argv) | |||
254 | 254 | ||
255 | short_tty = full_tty; | 255 | short_tty = full_tty; |
256 | username[0] = '\0'; | 256 | username[0] = '\0'; |
257 | amroot = (getuid() == 0); | ||
258 | signal(SIGALRM, alarm_handler); | 257 | signal(SIGALRM, alarm_handler); |
259 | alarm(TIMEOUT); | 258 | alarm(TIMEOUT); |
260 | 259 | ||
260 | /* More of suid paranoia if called by non-root */ | ||
261 | amroot = !sanitize_env_if_suid(); /* Clear dangerous stuff, set PATH */ | ||
262 | |||
261 | /* Mandatory paranoia for suid applet: | 263 | /* Mandatory paranoia for suid applet: |
262 | * ensure that fd# 0,1,2 are opened (at least to /dev/null) | 264 | * ensure that fd# 0,1,2 are opened (at least to /dev/null) |
263 | * and any extra open fd's are closed. | 265 | * and any extra open fd's are closed. |
264 | * (The name of the function is misleading. Not daemonizing here.) */ | 266 | * (The name of the function is misleading. Not daemonizing here.) */ |
265 | bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); | 267 | bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); |
266 | /* More of suid paranoia if called by non-root */ | ||
267 | if (!amroot) { | ||
268 | /* Clear dangerous stuff, set PATH */ | ||
269 | sanitize_env_for_suid(); | ||
270 | } | ||
271 | 268 | ||
272 | opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); | 269 | opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); |
273 | if (opt & LOGIN_OPT_f) { | 270 | if (opt & LOGIN_OPT_f) { |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index faa93eaea..3a1a8e9f5 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -49,7 +49,7 @@ int sulogin_main(int argc, char **argv) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | /* Clear dangerous stuff, set PATH */ | 51 | /* Clear dangerous stuff, set PATH */ |
52 | sanitize_env_for_suid(); | 52 | sanitize_env_if_suid(); |
53 | 53 | ||
54 | // bb_askpass() already handles this | 54 | // bb_askpass() already handles this |
55 | // signal(SIGALRM, catchalarm); | 55 | // signal(SIGALRM, catchalarm); |
diff --git a/miscutils/crontab.c b/miscutils/crontab.c index bc7f56a22..6b6896469 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c | |||
@@ -97,7 +97,6 @@ int crontab_main(int argc, char **argv) | |||
97 | char *user_name; /* -u USER */ | 97 | char *user_name; /* -u USER */ |
98 | int fd; | 98 | int fd; |
99 | int opt_ler; | 99 | int opt_ler; |
100 | uid_t my_uid; | ||
101 | 100 | ||
102 | /* file [opts] Replace crontab from file | 101 | /* file [opts] Replace crontab from file |
103 | * - [opts] Replace crontab from stdin | 102 | * - [opts] Replace crontab from stdin |
@@ -118,25 +117,22 @@ int crontab_main(int argc, char **argv) | |||
118 | OPT_ler = OPT_l + OPT_e + OPT_r, | 117 | OPT_ler = OPT_l + OPT_e + OPT_r, |
119 | }; | 118 | }; |
120 | 119 | ||
121 | my_uid = getuid(); | ||
122 | |||
123 | opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ | 120 | opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ |
124 | opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); | 121 | opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); |
125 | argv += optind; | 122 | argv += optind; |
126 | 123 | ||
127 | if (my_uid != geteuid()) { /* run by non-root? */ | 124 | if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ |
125 | /* run by non-root? */ | ||
128 | if (opt_ler & (OPT_u|OPT_c)) | 126 | if (opt_ler & (OPT_u|OPT_c)) |
129 | bb_error_msg_and_die("only root can use -c or -u"); | 127 | bb_error_msg_and_die("only root can use -c or -u"); |
130 | /* Clear dangerous stuff, set PATH */ | ||
131 | sanitize_env_for_suid(); | ||
132 | } | 128 | } |
133 | 129 | ||
134 | if (opt_ler & OPT_u) { | 130 | if (opt_ler & OPT_u) { |
135 | pas = getpwnam(user_name); | 131 | pas = getpwnam(user_name); |
136 | if (!pas) | 132 | if (!pas) |
137 | bb_error_msg_and_die("user %s is not known", user_name); | 133 | bb_error_msg_and_die("user %s is not known", user_name); |
138 | my_uid = pas->pw_uid; | ||
139 | } else { | 134 | } else { |
135 | uid_t my_uid = getuid(); | ||
140 | pas = getpwuid(my_uid); | 136 | pas = getpwuid(my_uid); |
141 | if (!pas) | 137 | if (!pas) |
142 | bb_perror_msg_and_die("no user record for UID %u", | 138 | bb_perror_msg_and_die("no user record for UID %u", |
@@ -144,7 +140,6 @@ int crontab_main(int argc, char **argv) | |||
144 | } | 140 | } |
145 | 141 | ||
146 | #define user_name DONT_USE_ME_BEYOND_THIS_POINT | 142 | #define user_name DONT_USE_ME_BEYOND_THIS_POINT |
147 | #define my_uid DONT_USE_ME_BEYOND_THIS_POINT | ||
148 | 143 | ||
149 | /* From now on, keep only -l, -e, -r bits */ | 144 | /* From now on, keep only -l, -e, -r bits */ |
150 | opt_ler &= OPT_ler; | 145 | opt_ler &= OPT_ler; |
diff --git a/networking/nc.c b/networking/nc.c index feb9c5db6..7c2aafaf6 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -44,14 +44,17 @@ int nc_main(int argc, char **argv) | |||
44 | while ((opt = getopt(argc, argv, | 44 | while ((opt = getopt(argc, argv, |
45 | "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 | 45 | "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 |
46 | ) { | 46 | ) { |
47 | if (ENABLE_NC_SERVER && opt=='l') USE_NC_SERVER(do_listen++); | 47 | if (ENABLE_NC_SERVER && opt=='l') |
48 | else if (ENABLE_NC_SERVER && opt=='p') { | 48 | USE_NC_SERVER(do_listen++); |
49 | else if (ENABLE_NC_SERVER && opt=='p') | ||
49 | USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); | 50 | USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); |
50 | } | 51 | else if (ENABLE_NC_EXTRA && opt=='w') |
51 | else if (ENABLE_NC_EXTRA && opt=='w') USE_NC_EXTRA( wsecs = xatou(optarg)); | 52 | USE_NC_EXTRA( wsecs = xatou(optarg)); |
52 | else if (ENABLE_NC_EXTRA && opt=='i') USE_NC_EXTRA( delay = xatou(optarg)); | 53 | else if (ENABLE_NC_EXTRA && opt=='i') |
53 | else if (ENABLE_NC_EXTRA && opt=='f') USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); | 54 | USE_NC_EXTRA( delay = xatou(optarg)); |
54 | else if (ENABLE_NC_EXTRA && opt=='e' && optind<=argc) { | 55 | else if (ENABLE_NC_EXTRA && opt=='f') |
56 | USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); | ||
57 | else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) { | ||
55 | /* We cannot just 'break'. We should let getopt finish. | 58 | /* We cannot just 'break'. We should let getopt finish. |
56 | ** Or else we won't be able to find where | 59 | ** Or else we won't be able to find where |
57 | ** 'host' and 'port' params are | 60 | ** 'host' and 'port' params are |
diff --git a/util-linux/mount.c b/util-linux/mount.c index dd753235e..054db57b3 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -33,6 +33,11 @@ | |||
33 | #ifndef MS_SILENT | 33 | #ifndef MS_SILENT |
34 | #define MS_SILENT (1 << 15) | 34 | #define MS_SILENT (1 << 15) |
35 | #endif | 35 | #endif |
36 | /* Grab more as needed from util-linux's mount/mount_constants.h */ | ||
37 | #ifndef MS_DIRSYNC | ||
38 | #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ | ||
39 | #endif | ||
40 | |||
36 | 41 | ||
37 | #if defined(__dietlibc__) | 42 | #if defined(__dietlibc__) |
38 | /* 16.12.2006, Sampo Kellomaki (sampo@iki.fi) | 43 | /* 16.12.2006, Sampo Kellomaki (sampo@iki.fi) |
@@ -122,6 +127,7 @@ static const int32_t mount_options[] = { | |||
122 | /* "exec" */ ~MS_NOEXEC, | 127 | /* "exec" */ ~MS_NOEXEC, |
123 | /* "noexec" */ MS_NOEXEC, | 128 | /* "noexec" */ MS_NOEXEC, |
124 | /* "sync" */ MS_SYNCHRONOUS, | 129 | /* "sync" */ MS_SYNCHRONOUS, |
130 | /* "dirsync" */ MS_DIRSYNC, | ||
125 | /* "async" */ ~MS_SYNCHRONOUS, | 131 | /* "async" */ ~MS_SYNCHRONOUS, |
126 | /* "atime" */ ~MS_NOATIME, | 132 | /* "atime" */ ~MS_NOATIME, |
127 | /* "noatime" */ MS_NOATIME, | 133 | /* "noatime" */ MS_NOATIME, |
@@ -171,6 +177,7 @@ static const char mount_option_str[] = | |||
171 | "exec" "\0" | 177 | "exec" "\0" |
172 | "noexec" "\0" | 178 | "noexec" "\0" |
173 | "sync" "\0" | 179 | "sync" "\0" |
180 | "dirsync" "\0" | ||
174 | "async" "\0" | 181 | "async" "\0" |
175 | "atime" "\0" | 182 | "atime" "\0" |
176 | "noatime" "\0" | 183 | "noatime" "\0" |
@@ -1665,6 +1672,8 @@ int mount_main(int argc, char **argv) | |||
1665 | SKIP_DESKTOP(const int nonroot = 0;) | 1672 | SKIP_DESKTOP(const int nonroot = 0;) |
1666 | USE_DESKTOP( int nonroot = (getuid() != 0);) | 1673 | USE_DESKTOP( int nonroot = (getuid() != 0);) |
1667 | 1674 | ||
1675 | sanitize_env_if_suid(); | ||
1676 | |||
1668 | /* parse long options, like --bind and --move. Note that -o option | 1677 | /* parse long options, like --bind and --move. Note that -o option |
1669 | * and --option are synonymous. Yes, this means --remount,rw works. */ | 1678 | * and --option are synonymous. Yes, this means --remount,rw works. */ |
1670 | 1679 | ||