aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-07 18:18:09 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-07 18:18:09 +0200
commit248a67fb75a0d2c98f4f9935b7bb9e11382b2c78 (patch)
treeeea88807a0b5d936d158ef7a62dfb051df174e96
parent316d38e25883c68e51533029dbab059ae0731de8 (diff)
downloadbusybox-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.lst18
-rw-r--r--coreutils/stat.c2
-rw-r--r--libbb/vfork_daemon_rexec.c2
-rw-r--r--procps/free.c7
-rw-r--r--procps/pgrep.c6
-rw-r--r--procps/pidof.c4
-rw-r--r--shell/ash.c2
-rw-r--r--shell/hush.c2
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
17Why can't be NOEXEC: 17Why can't be NOEXEC:
18suid: runs under different uid - must fork+exec 18suid: runs under different uid - must fork+exec
19if 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
20Why shouldn't be NOFORK/NOEXEC: 22Why shouldn't be NOFORK/NOEXEC:
21rare: not started often enough to bother optimizing (example: poweroff) 23rare: not started often enough to bother optimizing (example: poweroff)
@@ -131,7 +133,7 @@ flash_unlock - hardware
131flashcp - hardware 133flashcp - hardware
132flock - spawner, changes state (file locks), let's play safe and not be noexec 134flock - spawner, changes state (file locks), let's play safe and not be noexec
133fold - noexec. runner 135fold - noexec. runner
134free - nofork candidate(struct globals, needs to close /proc/meminfo fd) 136free - noexec. nofork candidate(struct globals, needs to close /proc/meminfo fd)
135freeramdisk - leaks: open+ioctl_or_perror_and_die 137freeramdisk - leaks: open+ioctl_or_perror_and_die
136fsck - interactive, longterm 138fsck - interactive, longterm
137fsck.minix - needs ^C 139fsck.minix - needs ^C
@@ -172,7 +174,7 @@ inotifyd - daemon
172insmod - noexec 174insmod - noexec
173install - runner 175install - runner
174ionice - noexec. spawner 176ionice - noexec. spawner
175iostat - runner 177iostat - longterm: "iostat 1" runs indefinitely
176ip - noexec candidate 178ip - noexec candidate
177ipaddr - noexec candidate 179ipaddr - noexec candidate
178ipcalc - noexec candidate 180ipcalc - noexec candidate
@@ -244,7 +246,7 @@ mv - noexec candidate, runner
244nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die 246nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
245nbd-client - noexec 247nbd-client - noexec
246nc - runner 248nc - runner
247netstat - runner with -c 249netstat - longterm with -c (continuous listing)
248nice - noexec. spawner 250nice - noexec. spawner
249nl - runner 251nl - runner
250nmeter - longterm 252nmeter - longterm
@@ -257,13 +259,13 @@ partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART)
257passwd - suid 259passwd - suid
258paste - noexec. runner 260paste - noexec. runner
259patch - needs ^C 261patch - needs ^C
260pgrep - nofork candidate(xregcomp, procps_scan - are they ok?) 262pgrep - must fork+exec to get correct /proc/PID/cmdline and comm field
261pidof - nofork candidate(uses find_pid_by_name, is that ok?) 263pidof - must fork+exec to get correct /proc/PID/cmdline and comm field
262ping - suid, longterm 264ping - suid, longterm
263ping6 - suid, longterm 265ping6 - suid, longterm
264pipe_progress - longterm 266pipe_progress - longterm
265pivot_root - NOFORK 267pivot_root - NOFORK
266pkill - nofork candidate(xregcomp, procps_scan - are they ok?) 268pkill - must fork+exec to get correct /proc/PID/cmdline and comm field
267pmap - noexec candidate, leaks: open+xstrdup 269pmap - noexec candidate, leaks: open+xstrdup
268popmaildir - runner 270popmaildir - runner
269poweroff - rare 271poweroff - rare
@@ -329,7 +331,7 @@ sort - noexec. runner
329split - runner 331split - runner
330ssl_client - longterm 332ssl_client - longterm
331start-stop-daemon - not noexec: uses bb_common_bufsiz1 333start-stop-daemon - not noexec: uses bb_common_bufsiz1
332stat - nofork candidate(needs fewer allocs) 334stat - noexec. nofork candidate(needs fewer allocs)
333strings - runner 335strings - runner
334stty - 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 336stty - 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
335su - suid, spawner 337su - suid, spawner
@@ -338,7 +340,7 @@ sum - runner
338sv - noexec. needs ^C (uses usleep(420000)) 340sv - noexec. needs ^C (uses usleep(420000))
339svc - noexec. needs ^C (uses usleep(420000)) 341svc - noexec. needs ^C (uses usleep(420000))
340svlogd - daemon 342svlogd - daemon
341swapoff - rare 343swapoff - longterm: may cause memory pressure, execing is beneficial
342swapon - rare 344swapon - rare
343switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode 345switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
344sync - NOFORK 346sync - 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
53static unsigned long long scale(unsigned long d) 56static 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