1Why an applet can't be NOFORK or NOEXEC?
2
3Why can't be NOFORK:
4interactive: may wait for user input, ^C has to work
5spawner: "tool PROG ARGS" which changes program state and execs - must fork
6changes state: e.g. environment, signal handlers
7leaks: 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
10talks 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
13runner: sometimes may run for long(ish) time, and/or works with network:
14	^C has to work (cat BIGFILE, chmod -R, ftpget, nc)
15
16"runners" can become eligible after shell is taught ^C to interrupt NOFORKs,
17need to be inspected that they do not fall into alloc+xfunc, open+xfunc,
18leak categories.
19
20Why can't be NOEXEC:
21suid: runs under different uid - must fork+exec
22if it's important that /proc/PID/cmdline and comm are correct.
23	("pkill sh" killing itself before it kills real "sh" is no fun)
24
25Why shouldn't be NOFORK/NOEXEC:
26rare: not started often enough to bother optimizing (example: poweroff)
27daemon: runs indefinitely; these are also always fit "rare" category
28longterm: often runs for a long time (many seconds), execing makes
29	memory footprint smaller
30complex: 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
33hardware: performs unusual hardware ops which may take long,
34	or even hang due to hardware or firmware bugs
35
36Interesting 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
38for users to keep it waiting for many minutes, whereas running "rm" in shell
39is very typical, and speeding up this common use via NOEXEC is useful.
40IOW: rm is "interactive", but not "longterm".
41
42Interesting example of an applet which can be NOFORK but if not,
43then should not be NOEXEC, is "usleep". As NOFORK, it amount to simply
44nanosleep()ing in the calling program (usually shell). No memory wasted.
45But if ran as NOEXEC, it would create a potentially long-term process,
46which would be taking more memory because it did not exec
47and did not free much of the copied memory of the parent
48(COW helps with this only as long as parent doesn't modify its memory).
49
50
51[ - NOFORK
52[[ - NOFORK
53acpid - daemon
54add-shell - noexec. leaks: open+xfunc
55addgroup - noexec. leaks
56adduser - noexec. leaks
57adjtimex - NOFORK
58ar - runner
59arch - NOFORK
60arp - talks to network: arp -n queries DNS
61arping - longterm
62ash - interactive, longterm
63awk - noexec. runner
64base64 - runner
65basename - NOFORK
66beep - longterm: beep -r 999999999
67blkdiscard - noexec. leaks: open+xioctl
68blkid - noexec
69blockdev - noexec. leaks fd
70bootchartd - daemon
71brctl - noexec
72bunzip2 - runner
73bzcat - runner
74bzip2 - runner
75cal - noexec. can be runner: cal -n9999
76cat - runner: cat HUGEFILE
77chat - longterm (when used as intended - talking to modem over stdin/out)
78chattr - noexec. runner
79chgrp - noexec. runner
80chmod - noexec. runner
81chown - noexec. runner
82chpasswd - longterm? (list of "user:password"s from stdin)
83chpst - noexec. spawner
84chroot - noexec. spawner
85chrt - noexec. spawner
86chvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
87cksum - noexec. runner
88clear - NOFORK
89cmp - runner
90comm - runner
91conspy - interactive, longterm
92cp - noexec. sometimes runner
93cpio - runner
94crond - daemon
95crontab - longterm (runs $EDITOR), leaks: open+xasprintf
96cryptpw - noexec. changes state: with --password-fd=N, moves N to stdin
97cttyhack - noexec. spawner
98cut - noexec. runner
99date - noexec. nofork candidate(needs to stop messing up env, free xasprintf result, not use xfuncs after xasprintf)
100dc - longterm (eats stdin if no params)
101dd - noexec. runner
102deallocvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
103delgroup - noexec. leaks
104deluser - noexec. leaks
105depmod - longterm(ish)
106devmem - hardware (access to device memory may hang)
107df - noexec. leaks: nested allocs
108dhcprelay - daemon
109diff - runner
110dirname - NOFORK
111dmesg - runner
112dnsd - daemon
113dnsdomainname - noexec. talks to network (may query DNS)
114dos2unix - noexec. runner
115dpkg - runner
116du - runner
117dumpkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
118dumpleases - noexec. leaks: open+xread
119echo - NOFORK
120ed - interactive, longterm
121egrep - longterm runner ("CMD | egrep ..."  may run indefinitely, better to exec to conserve memory)
122eject - hardware, leaks: open+ioctl_or_perror_and_die, changes state (moves fds)
123env - noexec. spawner, changes state (env)
124envdir - noexec. spawner
125envuidgid - noexec. spawner
126expand - runner
127expr - noexec. leaks: nested allocs
128factor - longterm (eats stdin if no params)
129fakeidentd - daemon
130false - NOFORK
131fatattr - noexec. leaks: open+xioctl, complex
132fbset - hardware, leaks: open+xfunc
133fbsplash - runner, longterm
134fdflush - hardware, leaks: open+ioctl_or_perror_and_die
135fdformat - hardware, longterm
136fdisk - interactive, longterm
137fgconsole - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
138fgrep - longterm runner ("CMD | fgrep ..."  may run indefinitely, better to exec to conserve memory)
139find - noexec. runner
140findfs - suid
141flash_eraseall - hardware
142flash_lock - hardware
143flash_unlock - hardware
144flashcp - hardware
145flock - spawner, changes state (file locks), let's play safe and not be noexec
146fold - noexec. runner
147free - NOFORK
148freeramdisk - noexec. leaks: open+ioctl_or_perror_and_die
149fsck - interactive, longterm
150fsck.minix - needs ^C
151fsfreeze - noexec. leaks: open+xioctl
152fstrim - noexec. leaks: open+xioctl, find_block_device -> readdir+xstrdup
153fsync - NOFORK
154ftpd - daemon
155ftpget - runner
156ftpput - runner
157fuser - complex
158getopt - noexec. leaks: many allocs
159getty - interactive, longterm
160grep - longterm runner ("CMD | grep ..."  may run indefinitely, better to exec to conserve memory)
161groups - noexec
162gunzip - runner
163gzip - runner
164halt - rare
165hd - noexec. runner
166hdparm - hardware
167head - noexec. runner
168hexdump - noexec. runner
169hexedit - interactive, longterm
170hostid - NOFORK
171hostname - noexec. talks to network (hostname -d may query DNS)
172httpd - daemon
173hush - interactive, longterm
174hwclock - hardware (xioctl(RTC_RD_TIME))
175i2cdetect - hardware
176i2cdump - hardware
177i2cget - hardware
178i2cset - hardware
179id - noexec
180ifconfig - hardware? (mem_start NN io_addr NN irq NN), leaks: xsocket+ioctl_or_perror_and_die
181ifenslave - noexec. leaks: xsocket+bb_perror_msg_and_die
182ifplugd - daemon
183inetd - daemon
184init - daemon
185inotifyd - daemon
186insmod - noexec
187install - runner
188ionice - noexec. spawner
189iostat - longterm: "iostat 1" runs indefinitely
190ip - noexec
191ipaddr - noexec
192ipcalc - noexec. ipcalc -h talks to network
193ipcrm - noexec
194ipcs - noexec
195iplink - noexec
196ipneigh - noexec
197iproute - noexec
198iprule - noexec
199iptunnel - noexec
200kbd_mode - noexec. leaks: xopen_nonblocking+xioctl
201kill - NOFORK
202killall - NOFORK
203killall5 - NOFORK
204klogd - daemon
205last - runner (I've got 1300 lines of output when tried it)
206less - interactive, longterm
207link - NOFORK
208linux32 - noexec. spawner
209linux64 - noexec. spawner
210linuxrc - daemon
211ln - noexec
212loadfont - noexec. leaks: config_open+bb_error_msg_and_die("map format")
213loadkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
214logger - runner
215login - suid, interactive, longterm
216logname - NOFORK
217losetup - noexec. complex
218lpd - daemon
219lpq - runner
220lpr - runner
221ls - noexec. runner
222lsattr - noexec. runner
223lsmod - noexec
224lsof - complex
225lspci - noexec. too rare to bother for nofork
226lsscsi - noexec. too rare to bother for nofork
227lsusb - noexec. too rare to bother for nofork
228lzcat - runner
229lzma - runner
230lzop - runner
231lzopcat - runner
232makedevs - noexec
233makemime - runner
234man - spawner, interactive, longterm
235md5sum - noexec. runner
236mdev - daemon
237mesg - NOFORK
238microcom - interactive, longterm
239minips - noexec
240mkdir - NOFORK
241mkdosfs - needs ^C
242mke2fs - needs ^C
243mkfifo - noexec
244mkfs.ext2 - needs ^C
245mkfs.minix - needs ^C
246mkfs.vfat - needs ^C
247mknod - noexec
248mkpasswd - noexec. changes state: with --password-fd=N, moves N to stdin
249mkswap - needs ^C
250mktemp - noexec. leaks: xstrdup+concat_path_file
251modinfo - noexec
252modprobe - noexec
253more - interactive, longterm
254mount - suid
255mountpoint - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
256mpstat - longterm: "mpstat 1" runs indefinitely
257mt - hardware
258mv - noexec. sometimes runner
259nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
260nbd-client - noexec
261nc - runner
262netstat - longterm with -c (continuous listing)
263nice - noexec. spawner
264nl - runner
265nmeter - longterm
266nohup - noexec. spawner
267nproc - NOFORK
268ntpd - daemon
269nuke - noexec
270od - runner
271openvt - longterm: spawns a child and waits for it
272partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART)
273passwd - suid
274paste - noexec. runner
275patch - needs ^C
276pgrep - must fork+exec to get correct /proc/PID/cmdline and comm field
277pidof - must fork+exec to get correct /proc/PID/cmdline and comm field
278ping - suid, longterm
279ping6 - suid, longterm
280pipe_progress - longterm
281pivot_root - NOFORK
282pkill - must fork+exec to get correct /proc/PID/cmdline and comm field
283pmap - noexec candidate, leaks: open+xstrdup
284popmaildir - runner
285poweroff - rare
286powertop - interactive, longterm
287printenv - NOFORK
288printf - NOFORK
289ps - noexec
290pscan - talks to network
291pstree - noexec
292pwd - NOFORK
293pwdx - NOFORK
294raidautorun - noexec. very simple. leaks: open+xioctl
295rdate - talks to network
296rdev - noexec. leaks: find_block_device -> readdir+xstrdup
297readlink - NOFORK
298readprofile - reads /boot/System.map and /proc/profile, better to free more memory by execing?
299realpath - NOFORK
300reboot - rare
301reformime - runner
302remove-shell - noexec. leaks: open+xfunc
303renice - noexec. nofork candidate(uses getpwnam, is that ok?)
304reset - noexec. spawner (execs "stty")
305resize - noexec. changes state (signal handlers)
306resume - noexec
307rev - runner
308rm - noexec. rm -i interactive
309rmdir - NOFORK
310rmmod - noexec
311route - talks to network (may query DNS to convert IPs to names)
312rpm - runner
313rpm2cpio - runner
314rtcwake - longterm: puts system to sleep, optimizing this for speed is pointless
315run-init - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
316run-parts - longterm
317runlevel - noexec. can be nofork if "endutxent()" is called unconditionally, but too rare to bother?
318runsv - daemon
319runsvdir - daemon
320rx - runner
321script - longterm: pumps script output from slave pty
322scriptreplay - longterm: plays back "script" saved output, sleeping as necessary.
323sed - runner
324sendmail - runner
325seq - noexec. runner
326setarch - noexec. spawner
327setconsole - noexec
328setfattr - noexec
329setfont - noexec. leaks a lot of stuff
330setkeycodes - noexec
331setlogcons - noexec
332setpriv - spawner, changes state, let's play safe and not be noexec
333setserial - noexec
334setsid - spawner, uses fork_or_rexec() [not audited to work in noexec], let's play safe and not be noexec
335setuidgid - noexec. spawner
336sha1sum - noexec. runner
337sha256sum - noexec. runner
338sha3sum - noexec. runner
339sha512sum - noexec. runner
340showkey - interactive, longterm
341shred - runner
342shuf - noexec. runner
343slattach - longterm (may sleep forever), uses bb_common_bufsiz1
344sleep - longterm. Could be nofork, if not the problem of "killall sleep" not killing it.
345smemcap - runner
346softlimit - noexec. spawner
347sort - noexec. runner
348split - runner
349ssl_client - longterm
350start-stop-daemon - not noexec: uses bb_common_bufsiz1
351stat - noexec. nofork candidate(needs fewer allocs)
352strings - runner
353stty - 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
354su - suid, spawner
355sulogin - noexec. spawner
356sum - runner
357sv - noexec. needs ^C (uses usleep(420000))
358svc - noexec. needs ^C (uses usleep(420000))
359svlogd - daemon
360swapoff - longterm: may cause memory pressure, execing is beneficial
361swapon - rare
362switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
363sync - NOFORK
364sysctl - noexec. leaks: xstrdup+xmalloc_read
365syslogd - daemon
366tac - noexec. runner
367tail - runner
368tar - runner
369taskset - noexec. spawner
370tcpsvd - daemon
371tee - runner
372telnet - interactive, longterm
373telnetd - daemon
374test - NOFORK
375tftp - runner
376tftpd - daemon
377time - spawner, longterm, changes state (signals)
378timeout - spawner, longterm, changes state (signals)
379top - interactive, longterm
380touch - NOFORK
381tr - runner
382traceroute - suid, longterm
383traceroute6 - suid, longterm
384true - NOFORK
385truncate - NOFORK
386tty - NOFORK
387ttysize - NOFORK
388tunctl - noexec
389tune2fs - noexec. leaks: open+xfunc
390ubiattach - hardware
391ubidetach - hardware
392ubimkvol - hardware
393ubirename - hardware
394ubirmvol - hardware
395ubirsvol - hardware
396ubiupdatevol - hardware
397udhcpc - daemon
398udhcpd - daemon
399udpsvd - daemon
400uevent - daemon
401umount - noexec. leaks: nested xmalloc
402uname - NOFORK
403uncompress - runner
404unexpand - runner
405uniq - runner
406unix2dos - noexec. runner
407unlink - NOFORK
408unlzma - runner
409unlzop - runner
410unxz - runner
411unzip - runner
412uptime - noexec. nofork candidate(is getutxent ok?)
413users - noexec. nofork candidate(is getutxent ok?)
414usleep - NOFORK. But what about "killall usleep"?
415uudecode - runner
416uuencode - runner
417vconfig - noexec. leaks: xsocket+ioctl_or_perror_and_die
418vi - interactive, longterm
419vlock - suid
420volname - hardware (reads CDROM, this can take long-ish if need to spin up)
421w - noexec. nofork candidate(is getutxent ok?)
422wall - suid
423watch - longterm
424watchdog - daemon
425wc - runner
426wget - longterm
427which - NOFORK
428who - noexec. nofork candidate(is getutxent ok?)
429whoami - NOFORK
430whois - talks to network
431xargs - noexec. spawner
432xxd - noexec. runner
433xz - runner
434xzcat - runner
435yes - noexec. runner
436zcat - runner
437zcip - daemon
438