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 runner: sometimes may run for long(ish) time, and/or works with network:
11 ^C has to work (cat BIGFILE, chmod -R, ftpget, nc)
13 "runners" can become eligible after shell is taught ^C to interrupt NOFORKs,
14 need to be inspected that they do not fall into alloc+xfunc, open+xfunc,
18 suid: runs under different uid - must fork+exec
20 Why shouldn't be NOFORK/NOEXEC:
21 rare: not started often enough to bother optimizing (example: poweroff)
22 daemon: runs indefinitely; these are also always fit "rare" category
23 longterm: often runs for a long time (many seconds), execing makes
24 memory footprint smaller
25 complex: no immediately obvious reason why NOFORK wouldn't work,
26 but does some non-obvoius operations (example: fuser, lsof, losetup);
27 detailed audit often turns out that it's a leaker
28 hardware: performs unusual hardware ops which may take long,
29 or even hang due to hardware or firmware bugs
31 Interesting example of "interactive" applet which is nevertheless can be
32 (and is) NOEXEC is "rm". Yes, "rm -i" is interactive - but it's not that typical
33 for users to keep it waiting for many minutes, whereas running "rm" in shell
34 is very typical, and speeding up this common use via NOEXEC is useful.
35 IOW: rm is "interactive", but not "longterm".
41 add-shell - noexec. leaks: open+xfunc
42 addgroup - noexec. leaks
43 adduser - noexec. leaks
47 arp - runner, needs ^C: arp -n talks to DNS servers
49 ash - interactive, longterm
53 beep - longterm: beep -r 999999999
54 blkdiscard - noexec. leaks: open+xioctl
56 blockdev - noexec. leaks fd
62 cal - runner: cal -n9999
64 chat - needs ^C to work
65 chattr - noexec. runner
66 chgrp - noexec. runner
67 chmod - noexec. runner
68 chown - noexec. runner
69 chpasswd - runner (list of "user:password"s from stdin)
70 chpst - noexec. spawner
71 chroot - noexec. spawner
72 chrt - noexec. spawner
73 chvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
74 cksum - noexec. runner
78 conspy - interactive, longterm
82 crontab - longterm (runs $EDITOR), leaks: open+xasprintf
83 cryptpw - noexec. changes state: with --password-fd=N, moves N to stdin
84 cttyhack - noexec. spawner
86 date - noexec. nofork candidate(needs to stop messing up env, free xasprintf result, not use xfuncs after xasprintf)
87 dc - runner (eats stdin if no params)
89 deallocvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
90 delgroup - noexec. leaks
91 deluser - noexec. leaks
92 depmod - longterm(ish)
93 devmem - runner, complex (access to device memory may hang)
94 df - leaks: nested allocs
100 dnsdomainname - needs ^C (may talk to DNS servers, which may be down)
101 dos2unix - noexec. runner
104 dumpkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
105 dumpleases - leaks: open+xread
107 ed - interactive, longterm
108 egrep - longterm runner ("CMD | egrep ..." may run indefinitely, better to exec to conserve memory)
109 eject - leaks: open+ioctl_or_perror_and_die, changes state (moves fds)
110 env - noexec. spawner, changes state (env)
111 envdir - noexec. spawner
112 envuidgid - noexec. spawner
114 expr - leaks: nested allocs
115 factor - runner (eats stdin if no params)
118 fatattr - leaks: open+xioctl, complex
119 fbset - hardware, leaks: open+xfunc
120 fbsplash - runner, longterm
121 fdflush - hardware, leaks: open+ioctl_or_perror_and_die
122 fdformat - hardware, needs ^C (floppy may be unresponsive), longterm
123 fdisk - interactive, longterm
124 fgconsole - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
125 fgrep - longterm runner ("CMD | fgrep ..." may run indefinitely, better to exec to conserve memory)
126 find - noexec. runner
128 flash_eraseall - hardware
129 flash_lock - hardware
130 flash_unlock - hardware
132 flock - spawner, changes state (file locks), let's play safe and not be noexec
133 fold - noexec. runner
134 free - nofork candidate(struct globals, needs to close /proc/meminfo fd)
135 freeramdisk - leaks: open+ioctl_or_perror_and_die
136 fsck - interactive, longterm
137 fsck.minix - needs ^C
138 fsfreeze - noexec. leaks: open+xioctl
139 fstrim - noexec. leaks: open+xioctl, find_block_device -> readdir+xstrdup
145 getopt - noexec. leaks: many allocs
146 getty - interactive, longterm
147 grep - longterm runner ("CMD | grep ..." may run indefinitely, better to exec to conserve memory)
154 head - noexec. runner
155 hexdump - noexec. runner
157 hostname - needs ^C (may talk to DNS servers, which may be down)
159 hush - interactive, longterm
160 hwclock - hardware (xioctl(RTC_RD_TIME))
166 ifconfig - leaks: xsocket+ioctl_or_perror_and_die
167 ifenslave - leaks: xsocket+bb_perror_msg_and_die
174 ionice - noexec. spawner
176 ip - noexec candidate
177 ipaddr - noexec candidate
178 ipcalc - noexec candidate
179 ipcrm - noexec candidate
180 ipcs - noexec candidate
181 iplink - noexec candidate
182 ipneigh - noexec candidate
183 iproute - noexec candidate
184 iprule - noexec candidate
185 iptunnel - noexec candidate
186 kbd_mode - noexec. leaks: xopen_nonblocking+xioctl
191 last - runner (I've got 1300 lines of output when tried it)
192 less - interactive, longterm
194 linux32 - noexec. spawner
195 linux64 - noexec. spawner
198 loadfont - noexec. leaks: config_open+bb_error_msg_and_die("map format")
199 loadkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
201 login - suid, interactive, longterm
208 lsattr - noexec. runner
211 lspci - noexec. too rare to bother for nofork
212 lsscsi - noexec. too rare to bother for nofork
213 lsusb - noexec. too rare to bother for nofork
220 man - spawner, interactive, longterm
221 md5sum - noexec. runner
224 microcom - interactive, longterm
230 mkfs.minix - needs ^C
233 mkpasswd - noexec. changes state: with --password-fd=N, moves N to stdin
235 mktemp - noexec. leaks: xstrdup+concat_path_file
238 more - interactive, longterm
240 mountpoint - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
241 mpstat - longterm: "mpstat 1" runs indefinitely
243 mv - noexec candidate, runner
244 nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
247 netstat - runner with -c
248 nice - noexec. spawner
251 nohup - noexec. spawner
255 openvt - longterm: spawns a child and waits for it
256 partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART)
258 paste - noexec. runner
260 pgrep - nofork candidate(xregcomp, procps_scan - are they ok?)
261 pidof - nofork candidate(uses find_pid_by_name, is that ok?)
262 ping - suid, longterm
263 ping6 - suid, longterm
264 pipe_progress - longterm
266 pkill - nofork candidate(xregcomp, procps_scan - are they ok?)
267 pmap - noexec candidate, leaks: open+xstrdup
270 powertop - interactive, longterm
273 ps - looks for AT_CLKTCK elf aux vector, therefore can't be noexec
278 raidautorun - noexec. very simple. leaks: open+xioctl
279 rdate - needs ^C (may talk to DNS servers, which may be down)
280 rdev - leaks: find_block_device -> readdir+xstrdup
282 readprofile - reads /boot/System.map and /proc/profile, better to free more memory by execing?
286 remove-shell - noexec. leaks: open+xfunc
287 renice - noexec. nofork candidate(uses getpwnam, is that ok?)
288 reset - noexec. spawner (execs "stty")
289 resize - noexec. changes state (signal handlers)
291 rm - noexec. rm -i interactive
294 route - needs ^C (may talk to DNS servers, which may be down)
297 rtcwake - longterm: puts system to sleep, optimizing this for speed is pointless
299 runlevel - noexec. can be nofork if "endutxent()" is called unconditionally, but too rare to bother?
303 script - longterm: pumps script output from slave pty
304 scriptreplay - longterm: plays back "script" saved output, sleeping as necessary.
308 setarch - noexec. spawner
310 setfont - noexec. leaks a lot of stuff
313 setpriv - spawner, changes state, let's play safe and not be noexec
315 setsid - spawner, uses fork_or_rexec() [not audited to work in noexec], let's play safe and not be noexec
316 setuidgid - noexec. spawner
317 sha1sum - noexec. runner
318 sha256sum - noexec. runner
319 sha3sum - noexec. runner
320 sha512sum - noexec. runner
321 showkey - interactive, longterm
323 shuf - noexec. runner
324 slattach - longterm (may sleep forever), uses bb_common_bufsiz1
325 sleep - runner, longterm
327 softlimit - noexec. spawner
328 sort - noexec. runner
330 ssl_client - longterm
331 start-stop-daemon - not noexec: uses bb_common_bufsiz1
332 stat - nofork candidate(needs fewer allocs)
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 sulogin - noexec. spawner
338 sv - noexec. needs ^C (uses usleep(420000))
339 svc - noexec. needs ^C (uses usleep(420000))
343 switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
345 sysctl - noexec. leaks: xstrdup+xmalloc_read
350 taskset - noexec. spawner
353 telnet - interactive, longterm
358 time - spawner, longterm, changes state (signals)
359 timeout - spawner, longterm, changes state (signals)
360 top - interactive, longterm
363 traceroute - suid, longterm
364 traceroute6 - suid, longterm
370 tune2fs - noexec. leaks: open+xfunc
377 ubiupdatevol - hardware
382 umount - noexec. leaks: nested xmalloc
387 unix2dos - noexec. runner
393 uptime - noexec. nofork candidate(is getutxent ok?)
394 users - noexec. nofork candidate(is getutxent ok?)
398 vconfig - leaks: xsocket+ioctl_or_perror_and_die
399 vi - interactive, longterm
402 w - noexec. nofork candidate(is getutxent ok?)
409 who - noexec. nofork candidate(is getutxent ok?)
412 xargs - noexec. spawner