diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-07 18:18:09 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-07 18:18:09 +0200 |
commit | 248a67fb75a0d2c98f4f9935b7bb9e11382b2c78 (patch) | |
tree | eea88807a0b5d936d158ef7a62dfb051df174e96 | |
parent | 316d38e25883c68e51533029dbab059ae0731de8 (diff) | |
download | busybox-w32-248a67fb75a0d2c98f4f9935b7bb9e11382b2c78.tar.gz busybox-w32-248a67fb75a0d2c98f4f9935b7bb9e11382b2c78.tar.bz2 busybox-w32-248a67fb75a0d2c98f4f9935b7bb9e11382b2c78.zip |
free,stat: make NOEXEC
pkill/pgrep/pidof uncovered another quirk: what about noexec's _process names_?
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | NOFORK_NOEXEC.lst | 18 | ||||
-rw-r--r-- | coreutils/stat.c | 2 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 2 | ||||
-rw-r--r-- | procps/free.c | 7 | ||||
-rw-r--r-- | procps/pgrep.c | 6 | ||||
-rw-r--r-- | procps/pidof.c | 4 | ||||
-rw-r--r-- | shell/ash.c | 2 | ||||
-rw-r--r-- | shell/hush.c | 2 |
8 files changed, 31 insertions, 12 deletions
diff --git a/NOFORK_NOEXEC.lst b/NOFORK_NOEXEC.lst index 70f38d867..8ec3bdbe6 100644 --- a/NOFORK_NOEXEC.lst +++ b/NOFORK_NOEXEC.lst | |||
@@ -16,6 +16,8 @@ leak categories. | |||
16 | 16 | ||
17 | Why can't be NOEXEC: | 17 | Why can't be NOEXEC: |
18 | suid: runs under different uid - must fork+exec | 18 | suid: runs under different uid - must fork+exec |
19 | if it's important that /proc/PID/cmdline and comm are correct. | ||
20 | ("pkill sh" killing itself before it kills real "sh" is no fun) | ||
19 | 21 | ||
20 | Why shouldn't be NOFORK/NOEXEC: | 22 | Why shouldn't be NOFORK/NOEXEC: |
21 | rare: not started often enough to bother optimizing (example: poweroff) | 23 | rare: not started often enough to bother optimizing (example: poweroff) |
@@ -131,7 +133,7 @@ flash_unlock - hardware | |||
131 | flashcp - hardware | 133 | flashcp - hardware |
132 | flock - spawner, changes state (file locks), let's play safe and not be noexec | 134 | flock - spawner, changes state (file locks), let's play safe and not be noexec |
133 | fold - noexec. runner | 135 | fold - noexec. runner |
134 | free - nofork candidate(struct globals, needs to close /proc/meminfo fd) | 136 | free - noexec. nofork candidate(struct globals, needs to close /proc/meminfo fd) |
135 | freeramdisk - leaks: open+ioctl_or_perror_and_die | 137 | freeramdisk - leaks: open+ioctl_or_perror_and_die |
136 | fsck - interactive, longterm | 138 | fsck - interactive, longterm |
137 | fsck.minix - needs ^C | 139 | fsck.minix - needs ^C |
@@ -172,7 +174,7 @@ inotifyd - daemon | |||
172 | insmod - noexec | 174 | insmod - noexec |
173 | install - runner | 175 | install - runner |
174 | ionice - noexec. spawner | 176 | ionice - noexec. spawner |
175 | iostat - runner | 177 | iostat - longterm: "iostat 1" runs indefinitely |
176 | ip - noexec candidate | 178 | ip - noexec candidate |
177 | ipaddr - noexec candidate | 179 | ipaddr - noexec candidate |
178 | ipcalc - noexec candidate | 180 | ipcalc - noexec candidate |
@@ -244,7 +246,7 @@ mv - noexec candidate, runner | |||
244 | nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die | 246 | nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die |
245 | nbd-client - noexec | 247 | nbd-client - noexec |
246 | nc - runner | 248 | nc - runner |
247 | netstat - runner with -c | 249 | netstat - longterm with -c (continuous listing) |
248 | nice - noexec. spawner | 250 | nice - noexec. spawner |
249 | nl - runner | 251 | nl - runner |
250 | nmeter - longterm | 252 | nmeter - longterm |
@@ -257,13 +259,13 @@ partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART) | |||
257 | passwd - suid | 259 | passwd - suid |
258 | paste - noexec. runner | 260 | paste - noexec. runner |
259 | patch - needs ^C | 261 | patch - needs ^C |
260 | pgrep - nofork candidate(xregcomp, procps_scan - are they ok?) | 262 | pgrep - must fork+exec to get correct /proc/PID/cmdline and comm field |
261 | pidof - nofork candidate(uses find_pid_by_name, is that ok?) | 263 | pidof - must fork+exec to get correct /proc/PID/cmdline and comm field |
262 | ping - suid, longterm | 264 | ping - suid, longterm |
263 | ping6 - suid, longterm | 265 | ping6 - suid, longterm |
264 | pipe_progress - longterm | 266 | pipe_progress - longterm |
265 | pivot_root - NOFORK | 267 | pivot_root - NOFORK |
266 | pkill - nofork candidate(xregcomp, procps_scan - are they ok?) | 268 | pkill - must fork+exec to get correct /proc/PID/cmdline and comm field |
267 | pmap - noexec candidate, leaks: open+xstrdup | 269 | pmap - noexec candidate, leaks: open+xstrdup |
268 | popmaildir - runner | 270 | popmaildir - runner |
269 | poweroff - rare | 271 | poweroff - rare |
@@ -329,7 +331,7 @@ sort - noexec. runner | |||
329 | split - runner | 331 | split - runner |
330 | ssl_client - longterm | 332 | ssl_client - longterm |
331 | start-stop-daemon - not noexec: uses bb_common_bufsiz1 | 333 | start-stop-daemon - not noexec: uses bb_common_bufsiz1 |
332 | stat - nofork candidate(needs fewer allocs) | 334 | stat - noexec. nofork candidate(needs fewer allocs) |
333 | strings - runner | 335 | strings - runner |
334 | stty - noexec. nofork candidate: has no allocs or opens except xmove_fd(xopen("-F DEVICE"),STDIN). tcsetattr(STDIN) is not a problem: it would work the same across processes sharing this fd | 336 | stty - noexec. nofork candidate: has no allocs or opens except xmove_fd(xopen("-F DEVICE"),STDIN). tcsetattr(STDIN) is not a problem: it would work the same across processes sharing this fd |
335 | su - suid, spawner | 337 | su - suid, spawner |
@@ -338,7 +340,7 @@ sum - runner | |||
338 | sv - noexec. needs ^C (uses usleep(420000)) | 340 | sv - noexec. needs ^C (uses usleep(420000)) |
339 | svc - noexec. needs ^C (uses usleep(420000)) | 341 | svc - noexec. needs ^C (uses usleep(420000)) |
340 | svlogd - daemon | 342 | svlogd - daemon |
341 | swapoff - rare | 343 | swapoff - longterm: may cause memory pressure, execing is beneficial |
342 | swapon - rare | 344 | swapon - rare |
343 | switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode | 345 | switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode |
344 | sync - NOFORK | 346 | sync - NOFORK |
diff --git a/coreutils/stat.c b/coreutils/stat.c index 3b85808b5..4e926a908 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
@@ -36,7 +36,7 @@ | |||
36 | //config: Without this, stat will not support the '-f' option to display | 36 | //config: Without this, stat will not support the '-f' option to display |
37 | //config: information about filesystem status. | 37 | //config: information about filesystem status. |
38 | 38 | ||
39 | //applet:IF_STAT(APPLET(stat, BB_DIR_BIN, BB_SUID_DROP)) | 39 | //applet:IF_STAT(APPLET_NOEXEC(stat, stat, BB_DIR_BIN, BB_SUID_DROP, stat)) |
40 | 40 | ||
41 | //kbuild:lib-$(CONFIG_STAT) += stat.o | 41 | //kbuild:lib-$(CONFIG_STAT) += stat.o |
42 | 42 | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index f84e678b5..50ecea762 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -175,6 +175,8 @@ int FAST_FUNC spawn_and_wait(char **argv) | |||
175 | return wait4pid(rc); | 175 | return wait4pid(rc); |
176 | 176 | ||
177 | /* child */ | 177 | /* child */ |
178 | //TODO: prctl(PR_SET_NAME, (long)argv[0], 0, 0, 0);? [think pidof, pgrep, pkill] | ||
179 | //Rewrite /proc/PID/cmdline? (need to save argv0 and length at init for this to work!) | ||
178 | /* reset some state and run without execing */ | 180 | /* reset some state and run without execing */ |
179 | 181 | ||
180 | /* msg_eol = "\n"; - no caller needs this reinited yet */ | 182 | /* msg_eol = "\n"; - no caller needs this reinited yet */ |
diff --git a/procps/free.c b/procps/free.c index 618664e08..b57e4a322 100644 --- a/procps/free.c +++ b/procps/free.c | |||
@@ -15,7 +15,7 @@ | |||
15 | //config: memory in the system, as well as the buffers used by the kernel. | 15 | //config: memory in the system, as well as the buffers used by the kernel. |
16 | //config: The shared memory column should be ignored; it is obsolete. | 16 | //config: The shared memory column should be ignored; it is obsolete. |
17 | 17 | ||
18 | //applet:IF_FREE(APPLET(free, BB_DIR_USR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_FREE(APPLET_NOEXEC(free, free, BB_DIR_USR_BIN, BB_SUID_DROP, free)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_FREE) += free.o | 20 | //kbuild:lib-$(CONFIG_FREE) += free.o |
21 | 21 | ||
@@ -47,7 +47,10 @@ struct globals { | |||
47 | #endif | 47 | #endif |
48 | } FIX_ALIASING; | 48 | } FIX_ALIASING; |
49 | #define G (*(struct globals*)bb_common_bufsiz1) | 49 | #define G (*(struct globals*)bb_common_bufsiz1) |
50 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 50 | #define INIT_G() do { \ |
51 | setup_common_bufsiz(); \ | ||
52 | /* NB: noexec applet - globals not zeroed */ \ | ||
53 | } while (0) | ||
51 | 54 | ||
52 | 55 | ||
53 | static unsigned long long scale(unsigned long d) | 56 | static unsigned long long scale(unsigned long d) |
diff --git a/procps/pgrep.c b/procps/pgrep.c index a3ca9e295..a16a6e959 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c | |||
@@ -18,9 +18,13 @@ | |||
18 | //config: help | 18 | //config: help |
19 | //config: Send signals to processes by name. | 19 | //config: Send signals to processes by name. |
20 | 20 | ||
21 | //applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) | 21 | //applet:IF_PGREP(APPLET_ODDNAME(pgrep, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pgrep)) |
22 | // APPLET_ODDNAME:name main location suid_type help | 22 | // APPLET_ODDNAME:name main location suid_type help |
23 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) | 23 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) |
24 | /* can't be noexec: can find _itself_ under wrong name, since after fork only, | ||
25 | * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)), | ||
26 | * but cmdline? | ||
27 | */ | ||
24 | 28 | ||
25 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o | 29 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o |
26 | //kbuild:lib-$(CONFIG_PKILL) += pgrep.o | 30 | //kbuild:lib-$(CONFIG_PKILL) += pgrep.o |
diff --git a/procps/pidof.c b/procps/pidof.c index 41247a02c..98d7949f8 100644 --- a/procps/pidof.c +++ b/procps/pidof.c | |||
@@ -30,6 +30,10 @@ | |||
30 | //config: of the pidof, in other words the calling shell or shell script. | 30 | //config: of the pidof, in other words the calling shell or shell script. |
31 | 31 | ||
32 | //applet:IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) | 32 | //applet:IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) |
33 | /* can't be noexec: can find _itself_ under wrong name, since after fork only, | ||
34 | * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)), | ||
35 | * but cmdline? | ||
36 | */ | ||
33 | 37 | ||
34 | //kbuild:lib-$(CONFIG_PIDOF) += pidof.o | 38 | //kbuild:lib-$(CONFIG_PIDOF) += pidof.o |
35 | 39 | ||
diff --git a/shell/ash.c b/shell/ash.c index e8f3ed26b..0a323e957 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -7803,6 +7803,8 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
7803 | while (*envp) | 7803 | while (*envp) |
7804 | putenv(*envp++); | 7804 | putenv(*envp++); |
7805 | popredir(/*drop:*/ 1); | 7805 | popredir(/*drop:*/ 1); |
7806 | //TODO: prctl(PR_SET_NAME, (long)argv[0], 0, 0, 0);? [think pidof, pgrep, pkill] | ||
7807 | //Rewrite /proc/PID/cmdline? (need to save argv0 and length at init for this to work!) | ||
7806 | run_applet_no_and_exit(applet_no, cmd, argv); | 7808 | run_applet_no_and_exit(applet_no, cmd, argv); |
7807 | } | 7809 | } |
7808 | /* re-exec ourselves with the new arguments */ | 7810 | /* re-exec ourselves with the new arguments */ |
diff --git a/shell/hush.c b/shell/hush.c index bb80f422c..b4fe7146b 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7387,6 +7387,8 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
7387 | /* Without this, "rm -i FILE" can't be ^C'ed: */ | 7387 | /* Without this, "rm -i FILE" can't be ^C'ed: */ |
7388 | switch_off_special_sigs(G.special_sig_mask); | 7388 | switch_off_special_sigs(G.special_sig_mask); |
7389 | debug_printf_exec("running applet '%s'\n", argv[0]); | 7389 | debug_printf_exec("running applet '%s'\n", argv[0]); |
7390 | //TODO: prctl(PR_SET_NAME, (long)argv[0], 0, 0, 0);? [think pidof, pgrep, pkill] | ||
7391 | //Rewrite /proc/PID/cmdline? (need to save argv0 and length at init for this to work!) | ||
7390 | run_applet_no_and_exit(a, argv[0], argv); | 7392 | run_applet_no_and_exit(a, argv[0], argv); |
7391 | } | 7393 | } |
7392 | # endif | 7394 | # endif |