5cb907fffc
BTW, I failed to make it do what it meant to do. ioctl appears to succeed, but kernel's output is not coming to the specified console (tried on VT consoles too). OTOH, setlogcons does work... 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. leaks fd
|
|
bootchartd - daemon
|
|
brctl
|
|
bunzip2 - runner
|
|
busybox
|
|
bzcat - runner
|
|
bzip2 - runner
|
|
cal - runner: cal -n9999
|
|
cat - runner
|
|
chat - needs ^C to work
|
|
chattr - noexec. 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 - 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, longterm
|
|
cp - noexec. runner
|
|
cpio - runner
|
|
crond - daemon
|
|
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 - runner (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
|
|
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 - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
|
|
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 - 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 - 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. leaks: open+xioctl
|
|
fstrim - noexec. 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 - noexec. 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 - noexec. leaks: get_console_fd_or_die() may open a new fd, or return one of stdio fds
|
|
logger - runner
|
|
login - suid, interactive, longterm
|
|
logname - NOFORK
|
|
losetup - complex
|
|
lpd - daemon
|
|
lpq - runner
|
|
lpr - runner
|
|
ls - noexec. runner
|
|
lsattr - noexec. runner
|
|
lsmod - noexec
|
|
lsof - complex
|
|
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
|
|
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 - 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 - noexec. leaks: option -n "print dev name": find_block_device -> readdir+xstrdup
|
|
mpstat - longterm: "mpstat 1" runs indefinitely
|
|
mt - rare
|
|
mv - noexec candidate, runner
|
|
nameif - noexec. openlog(), 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. 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
|
|
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 - looks for AT_CLKTCK elf aux vector, therefore can't be noexec
|
|
pscan - longterm
|
|
pstree - noexec
|
|
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 - noexec
|
|
setfont
|
|
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 - longterm (may sleep forever), uses bb_common_bufsiz1
|
|
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. needs ^C (uses usleep(420000))
|
|
svc - noexec. 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. 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 - noexec
|
|
tune2fs - noexec. leaks: open+xfunc
|
|
ubiattach
|
|
ubidetach
|
|
ubimkvol
|
|
ubirename
|
|
ubirmvol
|
|
ubirsvol
|
|
ubiupdatevol
|
|
udhcpc - daemon
|
|
udhcpd - daemon
|
|
udpsvd - daemon
|
|
uevent - daemon
|
|
umount - noexec. 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
|