692eeb81a4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
418 lines
12 KiB
Plaintext
418 lines
12 KiB
Plaintext
Why an applet can't be NOFORK or NOEXEC?
|
|
|
|
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
|
|
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 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
|
|
|
|
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);
|
|
detailed audit often turns out that it's a leaker
|
|
|
|
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".
|
|
|
|
|
|
[ - NOFORK
|
|
[[ - NOFORK
|
|
acpid - daemon
|
|
add-shell
|
|
addgroup
|
|
adduser
|
|
adjtimex
|
|
ar - runner
|
|
arch - NOFORK
|
|
arp - complex, rare
|
|
arping - runner
|
|
ash - interactive, longterm
|
|
awk - noexec. runner
|
|
base64 - runner
|
|
basename - NOFORK
|
|
beep
|
|
blkdiscard
|
|
blkid
|
|
blockdev - noexec candidate (rather simple), leaks fd
|
|
bootchartd - daemon
|
|
brctl
|
|
bunzip2 - runner
|
|
busybox
|
|
bzcat - runner
|
|
bzip2 - runner
|
|
cal - runner: cal -n9999
|
|
cat - runner
|
|
chat - needs ^C to work
|
|
chattr - runner
|
|
chgrp - noexec. runner
|
|
chmod - noexec. runner
|
|
chown - noexec. runner
|
|
chpasswd - runner (list of "user:password"s from stdin)
|
|
chpst - noexec. spawner
|
|
chroot - noexec. spawner
|
|
chrt - noexec. spawner
|
|
chvt - leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds. Also, "rare" category. noexec candidate.
|
|
cksum - noexec. runner
|
|
clear - NOFORK
|
|
cmp - runner
|
|
comm - runner
|
|
conspy - interactive, longterm
|
|
cp - noexec. runner
|
|
cpio - runner
|
|
crond - daemon
|
|
crontab 0 leaks: open+xasprintf
|
|
cryptpw - changes state: with --password-fd=N, moves N to stdin. Also, "rare" category. noexec candidate.
|
|
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)
|
|
dd - noexec. runner
|
|
deallocvt - leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds. Also, "rare" category. noexec candidate.
|
|
delgroup
|
|
deluser
|
|
depmod - complex, rare
|
|
devmem - runner, complex (access to device memory may hang)
|
|
df - 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)
|
|
dos2unix - noexec. runner
|
|
dpkg - runner
|
|
du - runner
|
|
dumpkmap - leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds. Also, "rare" category. noexec candidate.
|
|
dumpleases - 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)
|
|
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)
|
|
fakeidentd - daemon
|
|
false - NOFORK
|
|
fatattr - leaks: open+xioctl, complex
|
|
fbset - leaks: open+xfunc, complex, rare
|
|
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
|
|
fdisk - interactive, longterm
|
|
fgconsole - leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds. Also, "rare" category. noexec candidate.
|
|
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 - 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
|
|
fsck - interactive, longterm
|
|
fsck.minix - needs ^C
|
|
fsfreeze - noexec candidate (it's very simple), leaks: open+xioctl
|
|
fstrim - noexec candidate (it's very simple), leaks: open+xioctl, find_block_device -> readdir+xstrdup
|
|
fsync - NOFORK
|
|
ftpd - daemon
|
|
ftpget - runner
|
|
ftpput - runner
|
|
fuser - complex
|
|
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
|
|
hostid - NOFORK
|
|
hostname - needs ^C (may talk to DNS servers, which may be down)
|
|
httpd - daemon
|
|
hush - interactive, longterm
|
|
hwclock - talks to hardware (xioctl(RTC_RD_TIME)) - needs ^C
|
|
i2cdetect
|
|
i2cdump
|
|
i2cget
|
|
i2cset
|
|
id - noexec
|
|
ifconfig - leaks: xsocket+ioctl_or_perror_and_die
|
|
ifenslave - leaks: xsocket+bb_perror_msg_and_die
|
|
ifplugd - daemon
|
|
inetd - daemon
|
|
init - daemon
|
|
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
|
|
kbd_mode - leaks: xopen_nonblocking+xioctl
|
|
kill - NOFORK
|
|
killall - NOFORK
|
|
killall5 - NOFORK
|
|
klogd - daemon
|
|
last - runner (I've got 1300 lines of output when tried it)
|
|
less - interactive, longterm
|
|
link - NOFORK
|
|
linux32 - noexec. spawner
|
|
linux64 - noexec. spawner
|
|
linuxrc - daemon
|
|
ln - noexec
|
|
loadfont - leaks: config_open+bb_error_msg_and_die("map format")
|
|
loadkmap - leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds. Also, "rare" category. noexec candidate.
|
|
logger - runner
|
|
login - suid, interactive, longterm
|
|
logname - NOFORK
|
|
losetup - complex
|
|
lpd - daemon
|
|
lpq - runner
|
|
lpr - runner
|
|
ls - noexec. runner
|
|
lsattr - runner. noexec candidate (ls is, why not this one?)
|
|
lsmod - noexec
|
|
lsof - complex
|
|
lspci - noexec candidate, too rare to bother for nofork
|
|
lsscsi - noexec candidate, too rare to bother for nofork
|
|
lsusb - noexec candidate, too rare to bother for nofork
|
|
lzcat - runner
|
|
lzma - runner
|
|
lzop - runner
|
|
lzopcat - runner
|
|
makedevs
|
|
makemime - runner
|
|
man - spawner, interactive, longterm
|
|
md5sum - noexec. runner
|
|
mdev - daemon
|
|
mesg - NOFORK
|
|
microcom - interactive, longterm
|
|
mkdir - NOFORK
|
|
mkdosfs - needs ^C
|
|
mke2fs - needs ^C
|
|
mkfifo - noexec
|
|
mkfs.ext2 - needs ^C
|
|
mkfs.minix - needs ^C
|
|
mkfs.vfat - needs ^C
|
|
mknod - noexec
|
|
mkpasswd - changes state: with --password-fd=N, moves N to stdin. Also, "rare" category. noexec candidate.
|
|
mkswap - needs ^C
|
|
mktemp - noexec. leaks: xstrdup+concat_path_file
|
|
modinfo - noexec
|
|
modprobe - noexec
|
|
more - interactive, longterm
|
|
mount - suid
|
|
mountpoint - noexec candidate, leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
|
|
mpstat - noexec candidate (it's a measuring tool, putting less load by itself is good), complex
|
|
mt - rare
|
|
mv - noexec candidate, runner
|
|
nameif - leaks: config_open2+ioctl_or_perror_and_die
|
|
nbd-client
|
|
nc - runner
|
|
netstat - runner with -c
|
|
nice - noexec. spawner
|
|
nl - runner
|
|
nmeter - longterm
|
|
nohup - noexec. spawner
|
|
nproc - NOFORK
|
|
ntpd - daemon
|
|
od - runner
|
|
openvt - longterm: spawns a child and waits for it
|
|
partprobe - noexec candidate (simple), 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
|
|
pipe_progress - longterm
|
|
pivot_root - nofork candidate? the code is trivial
|
|
pkill - nofork candidate(xregcomp, procps_scan - are they ok?)
|
|
pmap - noexec candidate, leaks: open+xstrdup
|
|
popmaildir - runner
|
|
poweroff - rare
|
|
powertop - interactive, longterm
|
|
printenv - NOFORK
|
|
printf - NOFORK
|
|
ps - noexec candidate
|
|
pscan - longterm
|
|
pstree
|
|
pwd - NOFORK
|
|
pwdx - NOFORK
|
|
raidautorun
|
|
rdate - needs ^C (may talk to DNS servers, which may be down)
|
|
rdev - leaks: find_block_device -> readdir+xstrdup
|
|
readlink - NOFORK
|
|
readprofile
|
|
realpath - NOFORK
|
|
reboot - rare
|
|
reformime - runner
|
|
remove-shell
|
|
renice - nofork candidate(uses getpwnam, is that ok?)
|
|
reset - noexec. spawner (execs "stty")
|
|
resize - noexec. changes state (signal handlers)
|
|
rev - runner
|
|
rm - noexec. rm -i interactive
|
|
rmdir - NOFORK
|
|
rmmod - noexec
|
|
route - needs ^C (may talk to DNS servers, which may be down)
|
|
rpm - runner
|
|
rpm2cpio - runner
|
|
rtcwake - longterm: puts system to sleep, optimizing this for speed is pointless
|
|
run-parts
|
|
runlevel - noexec. can be nofork if "endutxent()" is called unconditionally, but too rare to bother?
|
|
runsv - daemon
|
|
runsvdir - daemon
|
|
rx - runner
|
|
script
|
|
scriptreplay
|
|
sed - runner
|
|
sendmail - runner
|
|
seq - noexec. runner
|
|
setarch - noexec. spawner
|
|
setconsole
|
|
setfont
|
|
setkeycodes
|
|
setlogcons
|
|
setpriv - spawner, changes state, let's play safe and not be noexec
|
|
setserial
|
|
setsid - spawner, uses fork_or_rexec() [not audted 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, longterm
|
|
smemcap - runner
|
|
softlimit - noexec. spawner
|
|
sort - noexec. runner
|
|
split - runner
|
|
ssl_client - longterm
|
|
start-stop-daemon
|
|
stat - 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
|
|
sulogin - noexec. spawner
|
|
sum - runner
|
|
sv - noexec candidate, needs ^C (uses usleep(420000))
|
|
svc - noexec candidate, needs ^C (uses usleep(420000))
|
|
svlogd - daemon
|
|
swapoff - rare
|
|
swapon - rare
|
|
switch_root - spawner, rare, changes state (oh yes), execing may be important to free binary's inode
|
|
sync - NOFORK
|
|
sysctl - noexec candidate, leaks: xstrdup+xmalloc_read
|
|
syslogd - daemon
|
|
tac - noexec. runner
|
|
tail - runner
|
|
tar - runner
|
|
taskset - noexec. spawner
|
|
tcpsvd - daemon
|
|
tee - runner
|
|
telnet - interactive, longterm
|
|
telnetd - daemon
|
|
test - NOFORK
|
|
tftp - runner
|
|
tftpd - daemon
|
|
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
|
|
true - NOFORK
|
|
truncate - NOFORK
|
|
tty - NOFORK
|
|
ttysize - NOFORK
|
|
tunctl
|
|
tune2fs - leaks: open+xfunc
|
|
ubiattach
|
|
ubidetach
|
|
ubimkvol
|
|
ubirename
|
|
ubirmvol
|
|
ubirsvol
|
|
ubiupdatevol
|
|
udhcpc - daemon
|
|
udhcpd - daemon
|
|
udpsvd - daemon
|
|
uevent - daemon
|
|
umount - noexec candidate, leaks: nested xmalloc
|
|
uname - NOFORK
|
|
uncompress - runner
|
|
unexpand - runner
|
|
uniq - runner
|
|
unix2dos - noexec. runner
|
|
unlink - NOFORK
|
|
unlzma - runner
|
|
unlzop - runner
|
|
unxz - runner
|
|
unzip - runner
|
|
uptime - nofork candidate(is getutxent ok?)
|
|
users - nofork candidate(is getutxent ok?)
|
|
usleep - NOFORK
|
|
uudecode - runner
|
|
uuencode - runner
|
|
vconfig - leaks: xsocket+ioctl_or_perror_and_die
|
|
vi - interactive, longterm
|
|
vlock - suid
|
|
volname - runner
|
|
w - nofork candidate(is getutxent ok?)
|
|
wall - suid
|
|
watch - longterm
|
|
watchdog - daemon
|
|
wc - runner
|
|
wget - longterm
|
|
which - NOFORK
|
|
who - nofork candidate(is getutxent ok?)
|
|
whoami - NOFORK
|
|
whois - needs ^C
|
|
xargs - noexec. spawner
|
|
xxd - noexec. runner
|
|
xz - runner
|
|
xzcat - runner
|
|
yes - noexec. runner
|
|
zcat - runner
|
|
zcip - daemon
|