Bump version to 1.32.0
[oweals/busybox.git] / NOFORK_NOEXEC.lst
index 02eba46e87bfd4b361fc5396d935f973fc26ded2..055f9fb24804ce95f9a519fadd60b6591c7428cf 100644 (file)
 Why an applet can't be NOFORK or NOEXEC?
 
 Why can't be NOFORK:
-daemon: runs indefinitely
 interactive: may wait for user input, ^C has to work
-spawner: "tool PROG ARGS" which changes program's environment - must fork
+spawner: "tool PROG ARGS" which changes program state and execs - must fork
 changes state: e.g. environment, signal handlers
-runner: sometimes may run for long time, and/or works with network:
+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)
 
-"runners" can become eligible after hush is taught ^C to interrupt NOFORKs!
+"runners" can become eligible after shell is taught ^C to interrupt NOFORKs,
+need to be inspected that they do not fall into alloc+xfunc, open+xfunc,
+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)
+daemon: runs indefinitely; these are also always fit "rare" category
+longterm: often runs for a long time (many seconds), execing makes
+       memory footprint smaller
 complex: no immediately obvious reason why NOFORK wouldn't work,
-       but does some non-obvoius operations (example: fuser, lsof, losetup).
-       for NOFORK, nested xmallocs (typical in complex code) is a problem.
-rare: not used often enough to bother optimizing (example: poweroff)
+       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
+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
-adjtimex
+add-shell - noexec. leaks: open+xfunc
+addgroup - noexec. leaks
+adduser - noexec. leaks
+adjtimex - NOFORK
 ar - runner
 arch - NOFORK
-arp
-arping - runner
-ash - interactive
-awk - noexec, runner
+arp - talks to network: arp -n queries DNS
+arping - longterm
+ash - interactive, longterm
+awk - noexec. runner
 base64 - runner
 basename - NOFORK
-beep
-blkdiscard
-blkid
-blockdev
+beep - longterm: beep -r 999999999
+blkdiscard - noexec. leaks: open+xioctl
+blkid - noexec
+blockdev - noexec. leaks fd
 bootchartd - daemon
-brctl
+brctl - noexec
 bunzip2 - runner
-busybox
 bzcat - runner
 bzip2 - runner
-cal
-cat - runner
-chat
-chattr - runner
-chgrp - noexec, runner
-chmod - noexec, runner
-chown - noexec, runner
-chpasswd - runner (list of "user:password"s from stdin)
-chpst - spawner
-chroot - spawner
-chrt - spawner
-chvt
-cksum - noexec, runner
+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 - longterm? (list of "user:password"s from stdin)
+chpst - noexec. spawner
+chroot - noexec. spawner
+chrt - noexec. spawner
+chvt - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
+cksum - noexec. runner
 clear - NOFORK
 cmp - runner
 comm - runner
-conspy - interactive
-cp - noexec, runner
+conspy - interactive, longterm
+cp - noexec. sometimes runner
 cpio - runner
 crond - daemon
-crontab
-cryptpw
-cttyhack - spawner
-cut - noexec, runner
-date
-dc - runner (eats stdin if no params)
-dd - noexec, runner
-deallocvt
-delgroup
-deluser
-depmod
-devmem
-df
+crontab - longterm (runs $EDITOR), leaks: open+xasprintf
+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 - 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 - 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
+dmesg - runner
 dnsd - daemon
-dnsdomainname
-dos2unix - noexec, runner
+dnsdomainname - noexec. talks to network (may query DNS)
+dos2unix - noexec. runner
 dpkg - runner
-du
-dumpkmap
-dumpleases
+du - runner
+dumpkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
+dumpleases - noexec. leaks: open+xread
 echo - NOFORK
-ed - interactive
-egrep - runner
-eject
-env - noexec, changes state (env)
-envdir - spawner
-envuidgid - spawner
+ed - interactive, longterm
+egrep - longterm runner ("CMD | egrep ..."  may run indefinitely, better to exec to conserve memory)
+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
-factor - runner (eats stdin if no params)
+expr - noexec. leaks: nested allocs
+factor - longterm (eats stdin if no params)
 fakeidentd - daemon
 false - NOFORK
-fatattr
-fbset
-fbsplash - runner, interactive
-fdflush
-fdformat - runner
-fdisk - interactive
-fgconsole
-fgrep - runner
-find - noexec, runner
+fatattr - noexec. leaks: open+xioctl, complex
+fbset - hardware, leaks: open+xfunc
+fbsplash - runner, longterm
+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
-flock
-fold - noexec, runner
-free
-freeramdisk
-fsck - interactive
-fsck.minix
-fsfreeze
-fstrim
+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
+freeramdisk - noexec. leaks: open+ioctl_or_perror_and_die
+fsck - interactive, longterm
+fsck.minix - needs ^C
+fsfreeze - noexec. leaks: open+xioctl
+fstrim - noexec. leaks: open+xioctl, find_block_device -> readdir+xstrdup
 fsync - NOFORK
 ftpd - daemon
 ftpget - runner
 ftpput - runner
 fuser - complex
-getopt
-getty - interactive
-grep - runner
+getopt - noexec. leaks: many allocs
+getty - interactive, longterm
+grep - longterm runner ("CMD | grep ..."  may run indefinitely, better to exec to conserve memory)
 groups - noexec
 gunzip - runner
 gzip - runner
 halt - rare
-hd - noexec, runner
-hdparm - complex, rare
-head - noexec, runner
-hexdump - noexec, runner
+hd - noexec. runner
+hdparm - hardware
+head - noexec. runner
+hexdump - noexec. runner
+hexedit - interactive, longterm
 hostid - NOFORK
-hostname
+hostname - noexec. talks to network (hostname -d may query DNS)
 httpd - daemon
-hush - interactive
-hwclock
-i2cdetect
-i2cdump
-i2cget
-i2cset
+hush - interactive, longterm
+hwclock - hardware (xioctl(RTC_RD_TIME))
+i2cdetect - hardware
+i2cdump - hardware
+i2cget - hardware
+i2cset - hardware
 id - noexec
-ifconfig
-ifenslave
+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
 inotifyd - daemon
-insmod
+insmod - noexec
 install - runner
-ionice - spawner
-iostat - runner
-ip
-ipaddr
-ipcalc
-ipcrm
-ipcs
-iplink
-ipneigh
-iproute
-iprule
-iptunnel
-kbd_mode
-kill
-killall
-killall5
+ionice - noexec. spawner
+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
+killall5 - NOFORK
 klogd - daemon
-last
-less - interactive
+last - runner (I've got 1300 lines of output when tried it)
+less - interactive, longterm
 link - NOFORK
-linux32 - spawner
-linux64 - spawner
+linux32 - noexec. spawner
+linux64 - noexec. spawner
 linuxrc - daemon
 ln - noexec
-loadfont
-loadkmap
+loadfont - noexec. leaks: config_open+bb_error_msg_and_die("map format")
+loadkmap - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
 logger - runner
-login - suid, interactive
+login - suid, interactive, longterm
 logname - NOFORK
-losetup - complex
+losetup - noexec. complex
 lpd - daemon
 lpq - runner
 lpr - runner
-ls - noexec, runner
-lsattr
-lsmod
+ls - noexec. runner
+lsattr - noexec. runner
+lsmod - noexec
 lsof - complex
-lspci
-lsscsi
-lsusb
+lspci - noexec. too rare to bother for nofork
+lsscsi - noexec. too rare to bother for nofork
+lsusb - noexec. too rare to bother for nofork
 lzcat - runner
 lzma - runner
 lzop - runner
 lzopcat - runner
-makedevs
+makedevs - noexec
 makemime - runner
-man - spawner, interactive
-md5sum - noexec, runner
+man - spawner, interactive, longterm
+md5sum - noexec. runner
 mdev - daemon
-mesg
-microcom - interactive, complex
+mesg - NOFORK
+microcom - interactive, longterm
+minips - noexec
 mkdir - NOFORK
-mkdosfs
-mke2fs
+mkdosfs - needs ^C
+mke2fs - needs ^C
 mkfifo - noexec
-mkfs.ext2
-mkfs.minix
-mkfs.vfat
+mkfs.ext2 - needs ^C
+mkfs.minix - needs ^C
+mkfs.vfat - needs ^C
 mknod - noexec
-mkpasswd
-mkswap
-mktemp
-modinfo
-modprobe
-more - interactive
+mkpasswd - noexec. changes state: with --password-fd=N, moves N to stdin
+mkswap - needs ^C
+mktemp - noexec. leaks: xstrdup+concat_path_file
+modinfo - noexec
+modprobe - noexec
+more - interactive, longterm
 mount - suid
-mountpoint
-mpstat
-mt
-mv
-nameif
-nbd-client
+mountpoint - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
+mpstat - longterm: "mpstat 1" runs indefinitely
+mt - hardware
+mv - noexec. sometimes runner
+nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die
+nbd-client - noexec
 nc - runner
-netstat
-nice - spawner
+netstat - longterm with -c (continuous listing)
+nice - noexec. spawner
 nl - runner
-nmeter - runner
-nohup - spawner
+nmeter - longterm
+nohup - noexec. spawner
 nproc - NOFORK
 ntpd - daemon
+nuke - noexec
 od - runner
-openvt - spawner
-partprobe
+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
-pgrep
-pidof
-ping - suid, runner
-ping6 - suid, runner
-pipe_progress
-pivot_root
-pkill
-pmap
+paste - noexec. runner
+patch - needs ^C
+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 - must fork+exec to get correct /proc/PID/cmdline and comm field
+pmap - noexec candidate, leaks: open+xstrdup
 popmaildir - runner
 poweroff - rare
-powertop - interactive
+powertop - interactive, longterm
 printenv - NOFORK
 printf - NOFORK
-ps
-pscan
-pstree
+ps - noexec
+pscan - talks to network
+pstree - noexec
 pwd - NOFORK
-pwdx
-raidautorun
-rdate
-rdev
-readlink
-readprofile
-realpath
+pwdx - NOFORK
+raidautorun - noexec. very simple. leaks: open+xioctl
+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
-reset - spawner (execs "stty")
-resize
+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
+rm - noexec. rm -i interactive
 rmdir - NOFORK
-rmmod
-route
+rmmod - noexec
+route - talks to network (may query DNS to convert IPs to names)
 rpm - runner
 rpm2cpio - runner
-rtcwake - complex, rare
-run-parts
-runlevel
+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 - spawner
-setconsole
-setfont
-setkeycodes
-setlogcons
-setpriv - spawner
-setserial
-setsid - spawner
-setuidgid
-sh - interactive
-sha1sum - noexec, runner
-sha256sum - noexec, runner
-sha3sum - noexec, runner
-sha512sum - noexec, runner
-showkey - interactive
+seq - noexec. runner
+setarch - noexec. spawner
+setconsole - noexec
+setfattr - noexec
+setfont - noexec. leaks a lot of stuff
+setkeycodes - noexec
+setlogcons - noexec
+setpriv - spawner, changes state, let's play safe and not be noexec
+setserial - noexec
+setsid - spawner, uses fork_or_rexec() [not audited to work in noexec], let's play safe and not be noexec
+setuidgid - noexec. spawner
+sha1sum - noexec. runner
+sha256sum - noexec. runner
+sha3sum - noexec. runner
+sha512sum - noexec. runner
+showkey - interactive, longterm
 shred - runner
-shuf - noexec, runner
-slattach
-sleep - runner
+shuf - noexec. runner
+slattach - longterm (may sleep forever), uses bb_common_bufsiz1
+sleep - longterm. Could be nofork, if not the problem of "killall sleep" not killing it.
 smemcap - runner
-softlimit - spawner
-sort - noexec, runner
+softlimit - noexec. spawner
+sort - noexec. runner
 split - runner
-ssl_client - network
-start-stop-daemon
-stat
+ssl_client - longterm
+start-stop-daemon - not noexec: uses bb_common_bufsiz1
+stat - noexec. nofork candidate(needs fewer allocs)
 strings - runner
-stty
+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
-sulogin - spawner
+sulogin - noexec. spawner
 sum - runner
-sv
-svc
+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, change state
+switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
 sync - NOFORK
-sysctl
+sysctl - noexec. leaks: xstrdup+xmalloc_read
 syslogd - daemon
-tac - noexec, runner
+tac - noexec. runner
 tail - runner
 tar - runner
-taskset - spawner
+taskset - noexec. spawner
 tcpsvd - daemon
 tee - runner
-telnet - interactive
+telnet - interactive, longterm
 telnetd - daemon
 test - NOFORK
 tftp - runner
 tftpd - daemon
-time - spawner, change state (signals)
-timeout - spawner, change state (signals)
-top - interactive
+time - spawner, longterm, changes state (signals)
+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
-tunctl
-tune2fs
-ubiattach
-ubidetach
-ubimkvol
-ubirename
-ubirmvol
-ubirsvol
-ubiupdatevol
+ttysize - NOFORK
+tunctl - noexec
+tune2fs - noexec. leaks: open+xfunc
+ubiattach - hardware
+ubidetach - hardware
+ubimkvol - hardware
+ubirename - hardware
+ubirmvol - hardware
+ubirsvol - hardware
+ubiupdatevol - hardware
 udhcpc - daemon
 udhcpd - daemon
 udpsvd - daemon
 uevent - daemon
-umount
+umount - noexec. leaks: nested xmalloc
 uname - NOFORK
 uncompress - runner
 unexpand - runner
 uniq - runner
-unix2dos - noexec, runner
+unix2dos - noexec. runner
 unlink - NOFORK
 unlzma - runner
 unlzop - runner
 unxz - runner
 unzip - runner
-uptime
-users
-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
-vi - interactive
+vconfig - noexec. leaks: xsocket+ioctl_or_perror_and_die
+vi - interactive, longterm
 vlock - suid
-volname - runner
-w
+volname - hardware (reads CDROM, this can take long-ish if need to spin up)
+w - noexec. nofork candidate(is getutxent ok?)
 wall - suid
-watch - runner
+watch - longterm
 watchdog - daemon
 wc - runner
-wget - runner
+wget - longterm
 which - NOFORK
-who
+who - noexec. nofork candidate(is getutxent ok?)
 whoami - NOFORK
-whois
-xargs - noexec, spawner
-xxd - noexec, runner
+whois - talks to network
+xargs - noexec. spawner
+xxd - noexec. runner
 xz - runner
 xzcat - runner
-yes - noexec, runner
+yes - noexec. runner
 zcat - runner
 zcip - daemon