Start 1.33.0 development cycle
[oweals/busybox.git] / NOFORK_NOEXEC.lst
index 63ec08643c3e6cc4ecc5a6e339db75aff22e6649..055f9fb24804ce95f9a519fadd60b6591c7428cf 100644 (file)
@@ -4,9 +4,12 @@ Why can't be NOFORK:
 interactive: may wait for user input, ^C has to work
 spawner: "tool PROG ARGS" which changes program state and execs - must fork
 changes state: e.g. environment, signal handlers
-alloc+xfunc: xmalloc, then xfunc - leaks memory if xfunc dies
-open+xfunc: opens fd, then calls xfunc - fd is leaked if xfunc dies
 leaks: does not free allocated memory or opened fds
+       alloc+xfunc: xmalloc, then xfunc - leaks memory if xfunc dies
+       open+xfunc: opens fd, then calls xfunc - fd is leaked if xfunc dies
+talks to network/serial/etc: it's not known how long the delay can be,
+       it's reasonable to expect it might be many seconds
+       (even if usually it is not), so ^C has to work
 runner: sometimes may run for long(ish) time, and/or works with network:
        ^C has to work (cat BIGFILE, chmod -R, ftpget, nc)
 
@@ -16,6 +19,8 @@ leak categories.
 
 Why can't be NOEXEC:
 suid: runs under different uid - must fork+exec
+if it's important that /proc/PID/cmdline and comm are correct.
+       ("pkill sh" killing itself before it kills real "sh" is no fun)
 
 Why shouldn't be NOFORK/NOEXEC:
 rare: not started often enough to bother optimizing (example: poweroff)
@@ -25,6 +30,8 @@ longterm: often runs for a long time (many seconds), execing makes
 complex: no immediately obvious reason why NOFORK wouldn't work,
        but does some non-obvoius operations (example: fuser, lsof, losetup);
        detailed audit often turns out that it's a leaker
+hardware: performs unusual hardware ops which may take long,
+       or even hang due to hardware or firmware bugs
 
 Interesting example of "interactive" applet which is nevertheless can be
 (and is) NOEXEC is "rm". Yes, "rm -i" is interactive - but it's not that typical
@@ -32,18 +39,26 @@ for users to keep it waiting for many minutes, whereas running "rm" in shell
 is very typical, and speeding up this common use via NOEXEC is useful.
 IOW: rm is "interactive", but not "longterm".
 
+Interesting example of an applet which can be NOFORK but if not,
+then should not be NOEXEC, is "usleep". As NOFORK, it amount to simply
+nanosleep()ing in the calling program (usually shell). No memory wasted.
+But if ran as NOEXEC, it would create a potentially long-term process,
+which would be taking more memory because it did not exec
+and did not free much of the copied memory of the parent
+(COW helps with this only as long as parent doesn't modify its memory).
+
 
 [ - NOFORK
 [[ - NOFORK
 acpid - daemon
-add-shell
-addgroup
-adduser
+add-shell - noexec. leaks: open+xfunc
+addgroup - noexec. leaks
+adduser - noexec. leaks
 adjtimex - NOFORK
 ar - runner
 arch - NOFORK
-arp - complex, rare
-arping - runner
+arp - talks to network: arp -n queries DNS
+arping - longterm
 ash - interactive, longterm
 awk - noexec. runner
 base64 - runner
@@ -55,17 +70,16 @@ blockdev - noexec. leaks fd
 bootchartd - daemon
 brctl - noexec
 bunzip2 - runner
-busybox
 bzcat - runner
 bzip2 - runner
-cal - runner: cal -n9999
-cat - runner
-chat - needs ^C to work
+cal - noexec. can be runner: cal -n9999
+cat - runner: cat HUGEFILE
+chat - longterm (when used as intended - talking to modem over stdin/out)
 chattr - noexec. runner
 chgrp - noexec. runner
 chmod - noexec. runner
 chown - noexec. runner
-chpasswd - runner (list of "user:password"s from stdin)
+chpasswd - longterm? (list of "user:password"s from stdin)
 chpst - noexec. spawner
 chroot - noexec. spawner
 chrt - noexec. spawner
@@ -75,7 +89,7 @@ clear - NOFORK
 cmp - runner
 comm - runner
 conspy - interactive, longterm
-cp - noexec. runner
+cp - noexec. sometimes runner
 cpio - runner
 crond - daemon
 crontab - longterm (runs $EDITOR), leaks: open+xasprintf
@@ -83,55 +97,55 @@ cryptpw - noexec. changes state: with --password-fd=N, moves N to stdin
 cttyhack - noexec. spawner
 cut - noexec. runner
 date - noexec. nofork candidate(needs to stop messing up env, free xasprintf result, not use xfuncs after xasprintf)
-dc - runner (eats stdin if no params)
+dc - longterm (eats stdin if no params)
 dd - noexec. runner
 deallocvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
-delgroup
-deluser
-depmod - complex, rare
-devmem - runner, complex (access to device memory may hang)
-df - leaks: nested allocs
+delgroup - noexec. leaks
+deluser - noexec. leaks
+depmod - longterm(ish)
+devmem - hardware (access to device memory may hang)
+df - noexec. leaks: nested allocs
 dhcprelay - daemon
 diff - runner
 dirname - NOFORK
 dmesg - runner
 dnsd - daemon
-dnsdomainname - needs ^C (may talk to DNS servers, which may be down)
+dnsdomainname - noexec. talks to network (may query DNS)
 dos2unix - noexec. runner
 dpkg - runner
 du - runner
 dumpkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
-dumpleases - leaks: open+xread
+dumpleases - noexec. leaks: open+xread
 echo - NOFORK
 ed - interactive, longterm
 egrep - longterm runner ("CMD | egrep ..."  may run indefinitely, better to exec to conserve memory)
-eject - leaks: open+ioctl_or_perror_and_die, changes state (moves fds)
+eject - hardware, leaks: open+ioctl_or_perror_and_die, changes state (moves fds)
 env - noexec. spawner, changes state (env)
 envdir - noexec. spawner
 envuidgid - noexec. spawner
 expand - runner
-expr - leaks: nested allocs
-factor - runner (eats stdin if no params)
+expr - noexec. leaks: nested allocs
+factor - longterm (eats stdin if no params)
 fakeidentd - daemon
 false - NOFORK
-fatattr - leaks: open+xioctl, complex
-fbset - leaks: open+xfunc, complex, rare
+fatattr - noexec. leaks: open+xioctl, complex
+fbset - hardware, leaks: open+xfunc
 fbsplash - runner, longterm
-fdflush - leaks: open+ioctl_or_perror_and_die, needs ^C (floppy may be unresponsive), rare
-fdformat - needs ^C (floppy may be unresponsive), longterm, rare
+fdflush - hardware, leaks: open+ioctl_or_perror_and_die
+fdformat - hardware, longterm
 fdisk - interactive, longterm
 fgconsole - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
 fgrep - longterm runner ("CMD | fgrep ..."  may run indefinitely, better to exec to conserve memory)
 find - noexec. runner
 findfs - suid
-flash_eraseall
-flash_lock
-flash_unlock
-flashcp - needs ^C. flash writing may be slow, better to free memory by execing
+flash_eraseall - hardware
+flash_lock - hardware
+flash_unlock - hardware
+flashcp - hardware
 flock - spawner, changes state (file locks), let's play safe and not be noexec
 fold - noexec. runner
-free - nofork candidate(struct globals, needs to close /proc/meminfo fd)
-freeramdisk - leaks: open+ioctl_or_perror_and_die
+free - NOFORK
+freeramdisk - noexec. leaks: open+ioctl_or_perror_and_die
 fsck - interactive, longterm
 fsck.minix - needs ^C
 fsfreeze - noexec. leaks: open+xioctl
@@ -149,21 +163,22 @@ gunzip - runner
 gzip - runner
 halt - rare
 hd - noexec. runner
-hdparm - complex, rare
+hdparm - hardware
 head - noexec. runner
 hexdump - noexec. runner
+hexedit - interactive, longterm
 hostid - NOFORK
-hostname - needs ^C (may talk to DNS servers, which may be down)
+hostname - noexec. talks to network (hostname -d may query DNS)
 httpd - daemon
 hush - interactive, longterm
-hwclock - talks to hardware (xioctl(RTC_RD_TIME)) - needs ^C
-i2cdetect
-i2cdump
-i2cget
-i2cset
+hwclock - hardware (xioctl(RTC_RD_TIME))
+i2cdetect - hardware
+i2cdump - hardware
+i2cget - hardware
+i2cset - hardware
 id - noexec
-ifconfig - leaks: xsocket+ioctl_or_perror_and_die
-ifenslave - leaks: xsocket+bb_perror_msg_and_die
+ifconfig - hardware? (mem_start NN io_addr NN irq NN), leaks: xsocket+ioctl_or_perror_and_die
+ifenslave - noexec. leaks: xsocket+bb_perror_msg_and_die
 ifplugd - daemon
 inetd - daemon
 init - daemon
@@ -171,17 +186,17 @@ inotifyd - daemon
 insmod - noexec
 install - runner
 ionice - noexec. spawner
-iostat - runner
-ip - noexec candidate
-ipaddr - noexec candidate
-ipcalc - noexec candidate
-ipcrm - noexec candidate
-ipcs - noexec candidate
-iplink - noexec candidate
-ipneigh - noexec candidate
-iproute - noexec candidate
-iprule - noexec candidate
-iptunnel - noexec candidate
+iostat - longterm: "iostat 1" runs indefinitely
+ip - noexec
+ipaddr - noexec
+ipcalc - noexec. ipcalc -h talks to network
+ipcrm - noexec
+ipcs - noexec
+iplink - noexec
+ipneigh - noexec
+iproute - noexec
+iprule - noexec
+iptunnel - noexec
 kbd_mode - noexec. leaks: xopen_nonblocking+xioctl
 kill - NOFORK
 killall - NOFORK
@@ -199,7 +214,7 @@ loadkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return o
 logger - runner
 login - suid, interactive, longterm
 logname - NOFORK
-losetup - complex
+losetup - noexec. complex
 lpd - daemon
 lpq - runner
 lpr - runner
@@ -221,6 +236,7 @@ md5sum - noexec. runner
 mdev - daemon
 mesg - NOFORK
 microcom - interactive, longterm
+minips - noexec
 mkdir - NOFORK
 mkdosfs - needs ^C
 mke2fs - needs ^C
@@ -238,74 +254,78 @@ more - interactive, longterm
 mount - suid
 mountpoint - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
 mpstat - longterm: "mpstat 1" runs indefinitely
-mt - rare
-mv - noexec candidate, runner
+mt - hardware
+mv - noexec. sometimes runner
 nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
-nbd-client
+nbd-client - noexec
 nc - runner
-netstat - runner with -c
+netstat - longterm with -c (continuous listing)
 nice - noexec. spawner
 nl - runner
 nmeter - longterm
 nohup - noexec. spawner
 nproc - NOFORK
 ntpd - daemon
+nuke - noexec
 od - runner
 openvt - longterm: spawns a child and waits for it
 partprobe - noexec. leaks: open+ioctl_or_perror_and_die(BLKRRPART)
 passwd - suid
 paste - noexec. runner
 patch - needs ^C
-pgrep - nofork candidate(xregcomp, procps_scan - are they ok?)
-pidof - nofork candidate(uses find_pid_by_name, is that ok?)
-ping - suid, runner
-ping6 - suid, runner
+pgrep - must fork+exec to get correct /proc/PID/cmdline and comm field
+pidof - must fork+exec to get correct /proc/PID/cmdline and comm field
+ping - suid, longterm
+ping6 - suid, longterm
 pipe_progress - longterm
 pivot_root - NOFORK
-pkill - nofork candidate(xregcomp, procps_scan - are they ok?)
+pkill - must fork+exec to get correct /proc/PID/cmdline and comm field
 pmap - noexec candidate, leaks: open+xstrdup
 popmaildir - runner
 poweroff - rare
 powertop - interactive, longterm
 printenv - NOFORK
 printf - NOFORK
-ps - looks for AT_CLKTCK elf aux vector, therefore can't be noexec
-pscan - longterm
+ps - noexec
+pscan - talks to network
 pstree - noexec
 pwd - NOFORK
 pwdx - NOFORK
 raidautorun - noexec. very simple. leaks: open+xioctl
-rdate - needs ^C (may talk to DNS servers, which may be down)
-rdev - leaks: find_block_device -> readdir+xstrdup
+rdate - talks to network
+rdev - noexec. leaks: find_block_device -> readdir+xstrdup
 readlink - NOFORK
 readprofile - reads /boot/System.map and /proc/profile, better to free more memory by execing?
 realpath - NOFORK
 reboot - rare
 reformime - runner
-remove-shell
-renice - nofork candidate(uses getpwnam, is that ok?)
+remove-shell - noexec. leaks: open+xfunc
+renice - noexec. nofork candidate(uses getpwnam, is that ok?)
 reset - noexec. spawner (execs "stty")
 resize - noexec. changes state (signal handlers)
+resume - noexec
 rev - runner
 rm - noexec. rm -i interactive
 rmdir - NOFORK
 rmmod - noexec
-route - needs ^C (may talk to DNS servers, which may be down)
+route - talks to network (may query DNS to convert IPs to names)
 rpm - runner
 rpm2cpio - runner
 rtcwake - longterm: puts system to sleep, optimizing this for speed is pointless
+run-init - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
 run-parts - longterm
 runlevel - noexec. can be nofork if "endutxent()" is called unconditionally, but too rare to bother?
 runsv - daemon
 runsvdir - daemon
 rx - runner
-script
-scriptreplay
+script - longterm: pumps script output from slave pty
+scriptreplay - longterm: plays back "script" saved output, sleeping as necessary.
 sed - runner
 sendmail - runner
 seq - noexec. runner
 setarch - noexec. spawner
 setconsole - noexec
+setfattr - noexec
 setfont - noexec. leaks a lot of stuff
 setkeycodes - noexec
 setlogcons - noexec
@@ -321,14 +341,14 @@ showkey - interactive, longterm
 shred - runner
 shuf - noexec. runner
 slattach - longterm (may sleep forever), uses bb_common_bufsiz1
-sleep - runner, longterm
+sleep - longterm. Could be nofork, if not the problem of "killall sleep" not killing it.
 smemcap - runner
 softlimit - noexec. spawner
 sort - noexec. runner
 split - runner
 ssl_client - longterm
 start-stop-daemon - not noexec: uses bb_common_bufsiz1
-stat - nofork candidate(needs fewer allocs)
+stat - noexec. nofork candidate(needs fewer allocs)
 strings - runner
 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
 su - suid, spawner
@@ -337,7 +357,7 @@ sum - runner
 sv - noexec. needs ^C (uses usleep(420000))
 svc - noexec. needs ^C (uses usleep(420000))
 svlogd - daemon
-swapoff - rare
+swapoff - longterm: may cause memory pressure, execing is beneficial
 swapon - rare
 switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
 sync - NOFORK
@@ -359,21 +379,21 @@ timeout - spawner, longterm, changes state (signals)
 top - interactive, longterm
 touch - NOFORK
 tr - runner
-traceroute - suid, runner
-traceroute6 - suid, runner
+traceroute - suid, longterm
+traceroute6 - suid, longterm
 true - NOFORK
 truncate - NOFORK
 tty - NOFORK
 ttysize - NOFORK
 tunctl - noexec
 tune2fs - noexec. leaks: open+xfunc
-ubiattach
-ubidetach
-ubimkvol
-ubirename
-ubirmvol
-ubirsvol
-ubiupdatevol
+ubiattach - hardware
+ubidetach - hardware
+ubimkvol - hardware
+ubirename - hardware
+ubirmvol - hardware
+ubirsvol - hardware
+ubiupdatevol - hardware
 udhcpc - daemon
 udhcpd - daemon
 udpsvd - daemon
@@ -389,25 +409,25 @@ unlzma - runner
 unlzop - runner
 unxz - runner
 unzip - runner
-uptime - nofork candidate(is getutxent ok?)
-users - nofork candidate(is getutxent ok?)
-usleep - NOFORK
+uptime - noexec. nofork candidate(is getutxent ok?)
+users - noexec. nofork candidate(is getutxent ok?)
+usleep - NOFORK. But what about "killall usleep"?
 uudecode - runner
 uuencode - runner
-vconfig - leaks: xsocket+ioctl_or_perror_and_die
+vconfig - noexec. leaks: xsocket+ioctl_or_perror_and_die
 vi - interactive, longterm
 vlock - suid
-volname - runner
-w - nofork candidate(is getutxent ok?)
+volname - hardware (reads CDROM, this can take long-ish if need to spin up)
+w - noexec. nofork candidate(is getutxent ok?)
 wall - suid
 watch - longterm
 watchdog - daemon
 wc - runner
 wget - longterm
 which - NOFORK
-who - nofork candidate(is getutxent ok?)
+who - noexec. nofork candidate(is getutxent ok?)
 whoami - NOFORK
-whois - needs ^C
+whois - talks to network
 xargs - noexec. spawner
 xxd - noexec. runner
 xz - runner