1 Why an applet can't be NOFORK or NOEXEC?
4 interactive: may wait for user input, ^C has to work
5 spawner: "tool PROG ARGS" which changes program state and execs - must fork
6 changes state: e.g. environment, signal handlers
7 leaks: does not free allocated memory or opened fds
8 alloc+xfunc: xmalloc, then xfunc - leaks memory if xfunc dies
9 open+xfunc: opens fd, then calls xfunc - fd is leaked if xfunc dies
10 talks to network/serial/etc: it's not known how long the delay can be,
11 it's reasonable to expect it might be many seconds
12 (even if usually it is not), so ^C has to work
13 runner: sometimes may run for long(ish) time, and/or works with network:
14 ^C has to work (cat BIGFILE, chmod -R, ftpget, nc)
16 "runners" can become eligible after shell is taught ^C to interrupt NOFORKs,
17 need to be inspected that they do not fall into alloc+xfunc, open+xfunc,
21 suid: runs under different uid - must fork+exec
22 if it's important that /proc/PID/cmdline and comm are correct.
23 ("pkill sh" killing itself before it kills real "sh" is no fun)
25 Why shouldn't be NOFORK/NOEXEC:
26 rare: not started often enough to bother optimizing (example: poweroff)
27 daemon: runs indefinitely; these are also always fit "rare" category
28 longterm: often runs for a long time (many seconds), execing makes
29 memory footprint smaller
30 complex: no immediately obvious reason why NOFORK wouldn't work,
31 but does some non-obvoius operations (example: fuser, lsof, losetup);
32 detailed audit often turns out that it's a leaker
33 hardware: performs unusual hardware ops which may take long,
34 or even hang due to hardware or firmware bugs
36 Interesting example of "interactive" applet which is nevertheless can be
37 (and is) NOEXEC is "rm". Yes, "rm -i" is interactive - but it's not that typical
38 for users to keep it waiting for many minutes, whereas running "rm" in shell
39 is very typical, and speeding up this common use via NOEXEC is useful.
40 IOW: rm is "interactive", but not "longterm".
46 add-shell - noexec. leaks: open+xfunc
47 addgroup - noexec. leaks
48 adduser - noexec. leaks
52 arp - talks to network: arp -n queries DNS
54 ash - interactive, longterm
58 beep - longterm: beep -r 999999999
59 blkdiscard - noexec. leaks: open+xioctl
61 blockdev - noexec. leaks fd
67 cal - runner: cal -n9999
68 cat - runner: cat HUGEFILE
69 chat - longterm (when used as intended - talking to modem over stdin/out)
70 chattr - noexec. runner
71 chgrp - noexec. runner
72 chmod - noexec. runner
73 chown - noexec. runner
74 chpasswd - longterm? (list of "user:password"s from stdin)
75 chpst - noexec. spawner
76 chroot - noexec. spawner
77 chrt - noexec. spawner
78 chvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
79 cksum - noexec. runner
83 conspy - interactive, longterm
87 crontab - longterm (runs $EDITOR), leaks: open+xasprintf
88 cryptpw - noexec. changes state: with --password-fd=N, moves N to stdin
89 cttyhack - noexec. spawner
91 date - noexec. nofork candidate(needs to stop messing up env, free xasprintf result, not use xfuncs after xasprintf)
92 dc - longterm (eats stdin if no params)
94 deallocvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
95 delgroup - noexec. leaks
96 deluser - noexec. leaks
97 depmod - longterm(ish)
98 devmem - hardware (access to device memory may hang)
99 df - noexec. leaks: nested allocs
105 dnsdomainname - noexec. talks to network (may query DNS)
106 dos2unix - noexec. runner
109 dumpkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
110 dumpleases - noexec. leaks: open+xread
112 ed - interactive, longterm
113 egrep - longterm runner ("CMD | egrep ..." may run indefinitely, better to exec to conserve memory)
114 eject - hardware, leaks: open+ioctl_or_perror_and_die, changes state (moves fds)
115 env - noexec. spawner, changes state (env)
116 envdir - noexec. spawner
117 envuidgid - noexec. spawner
119 expr - noexec. leaks: nested allocs
120 factor - longterm (eats stdin if no params)
123 fatattr - noexec. leaks: open+xioctl, complex
124 fbset - hardware, leaks: open+xfunc
125 fbsplash - runner, longterm
126 fdflush - hardware, leaks: open+ioctl_or_perror_and_die
127 fdformat - hardware, longterm
128 fdisk - interactive, longterm
129 fgconsole - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
130 fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory)
131 find - noexec. runner
133 flash_eraseall - hardware
134 flash_lock - hardware
135 flash_unlock - hardware
137 flock - spawner, changes state (file locks), let's play safe and not be noexec
138 fold - noexec. runner
139 free - noexec. nofork candidate(struct globals, needs to close /proc/meminfo fd)
140 freeramdisk - noexec. leaks: open+ioctl_or_perror_and_die
141 fsck - interactive, longterm
142 fsck.minix - needs ^C
143 fsfreeze - noexec. leaks: open+xioctl
144 fstrim - noexec. leaks: open+xioctl, find_block_device -> readdir+xstrdup
150 getopt - noexec. leaks: many allocs
151 getty - interactive, longterm
152 grep - longterm runner ("CMD | grep ..." may run indefinitely, better to exec to conserve memory)
159 head - noexec. runner
160 hexdump - noexec. runner
162 hostname - noexec. talks to network (hostname -d may query DNS)
164 hush - interactive, longterm
165 hwclock - hardware (xioctl(RTC_RD_TIME))
171 ifconfig - hardware? (mem_start NN io_addr NN irq NN), leaks: xsocket+ioctl_or_perror_and_die
172 ifenslave - noexec. leaks: xsocket+bb_perror_msg_and_die
179 ionice - noexec. spawner
180 iostat - longterm: "iostat 1" runs indefinitely
181 ip - noexec candidate
182 ipaddr - noexec candidate
183 ipcalc - noexec. ipcalc -h talks to network
184 ipcrm - noexec candidate
185 ipcs - noexec candidate
186 iplink - noexec candidate
187 ipneigh - noexec candidate
188 iproute - noexec candidate
189 iprule - noexec candidate
190 iptunnel - noexec candidate
191 kbd_mode - noexec. leaks: xopen_nonblocking+xioctl
196 last - runner (I've got 1300 lines of output when tried it)
197 less - interactive, longterm
199 linux32 - noexec. spawner
200 linux64 - noexec. spawner
203 loadfont - noexec. leaks: config_open+bb_error_msg_and_die("map format")
204 loadkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
206 login - suid, interactive, longterm
208 losetup - noexec. complex
213 lsattr - noexec. runner
216 lspci - noexec. too rare to bother for nofork
217 lsscsi - noexec. too rare to bother for nofork
218 lsusb - noexec. too rare to bother for nofork
225 man - spawner, interactive, longterm
226 md5sum - noexec. runner
229 microcom - interactive, longterm
235 mkfs.minix - needs ^C
238 mkpasswd - noexec. changes state: with --password-fd=N, moves N to stdin
240 mktemp - noexec. leaks: xstrdup+concat_path_file
243 more - interactive, longterm
245 mountpoint - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
246 mpstat - longterm: "mpstat 1" runs indefinitely
248 mv - noexec candidate, runner
249 nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
252 netstat - longterm with -c (continuous listing)
253 nice - noexec. spawner
256 nohup - noexec. spawner
260 openvt - longterm: spawns a child and waits for it
261 partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART)
263 paste - noexec. runner
265 pgrep - must fork+exec to get correct /proc/PID/cmdline and comm field
266 pidof - must fork+exec to get correct /proc/PID/cmdline and comm field
267 ping - suid, longterm
268 ping6 - suid, longterm
269 pipe_progress - longterm
271 pkill - must fork+exec to get correct /proc/PID/cmdline and comm field
272 pmap - noexec candidate, leaks: open+xstrdup
275 powertop - interactive, longterm
278 ps - looks for AT_CLKTCK elf aux vector, therefore can't be noexec
283 raidautorun - noexec. very simple. leaks: open+xioctl
284 rdate - talks to network
285 rdev - noexec. leaks: find_block_device -> readdir+xstrdup
287 readprofile - reads /boot/System.map and /proc/profile, better to free more memory by execing?
291 remove-shell - noexec. leaks: open+xfunc
292 renice - noexec. nofork candidate(uses getpwnam, is that ok?)
293 reset - noexec. spawner (execs "stty")
294 resize - noexec. changes state (signal handlers)
296 rm - noexec. rm -i interactive
299 route - talks to network (may query DNS to convert IPs to names)
302 rtcwake - longterm: puts system to sleep, optimizing this for speed is pointless
304 runlevel - noexec. can be nofork if "endutxent()" is called unconditionally, but too rare to bother?
308 script - longterm: pumps script output from slave pty
309 scriptreplay - longterm: plays back "script" saved output, sleeping as necessary.
313 setarch - noexec. spawner
315 setfont - noexec. leaks a lot of stuff
318 setpriv - spawner, changes state, let's play safe and not be noexec
320 setsid - spawner, uses fork_or_rexec() [not audited to work in noexec], let's play safe and not be noexec
321 setuidgid - noexec. spawner
322 sha1sum - noexec. runner
323 sha256sum - noexec. runner
324 sha3sum - noexec. runner
325 sha512sum - noexec. runner
326 showkey - interactive, longterm
328 shuf - noexec. runner
329 slattach - longterm (may sleep forever), uses bb_common_bufsiz1
330 sleep - runner, longterm
332 softlimit - noexec. spawner
333 sort - noexec. runner
335 ssl_client - longterm
336 start-stop-daemon - not noexec: uses bb_common_bufsiz1
337 stat - noexec. nofork candidate(needs fewer allocs)
339 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
341 sulogin - noexec. spawner
343 sv - noexec. needs ^C (uses usleep(420000))
344 svc - noexec. needs ^C (uses usleep(420000))
346 swapoff - longterm: may cause memory pressure, execing is beneficial
348 switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
350 sysctl - noexec. leaks: xstrdup+xmalloc_read
355 taskset - noexec. spawner
358 telnet - interactive, longterm
363 time - spawner, longterm, changes state (signals)
364 timeout - spawner, longterm, changes state (signals)
365 top - interactive, longterm
368 traceroute - suid, longterm
369 traceroute6 - suid, longterm
375 tune2fs - noexec. leaks: open+xfunc
382 ubiupdatevol - hardware
387 umount - noexec. leaks: nested xmalloc
392 unix2dos - noexec. runner
398 uptime - noexec. nofork candidate(is getutxent ok?)
399 users - noexec. nofork candidate(is getutxent ok?)
403 vconfig - noexec. leaks: xsocket+ioctl_or_perror_and_die
404 vi - interactive, longterm
406 volname - hardware (reads CDROM, this can take long-ish if need to spin up)
407 w - noexec. nofork candidate(is getutxent ok?)
414 who - noexec. nofork candidate(is getutxent ok?)
416 whois - talks to network
417 xargs - noexec. spawner