From 819b47aa357c33bf84919495795b36f8c1faa3ac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Aug 2017 03:29:32 +0200 Subject: new NOFORKs: clear, nproc, tty, uname, arch, unlink, which Signed-off-by: Denys Vlasenko --- NOFORK_NOEXEC.lst | 404 ++++++++++++++++++++++++++++++++++++++++++++++++++ console-tools/clear.c | 2 +- coreutils/nproc.c | 2 +- coreutils/tty.c | 2 +- coreutils/uname.c | 6 +- coreutils/unlink.c | 2 +- debianutils/which.c | 4 +- 7 files changed, 414 insertions(+), 8 deletions(-) create mode 100644 NOFORK_NOEXEC.lst diff --git a/NOFORK_NOEXEC.lst b/NOFORK_NOEXEC.lst new file mode 100644 index 000000000..02eba46e8 --- /dev/null +++ b/NOFORK_NOEXEC.lst @@ -0,0 +1,404 @@ +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 +changes state: e.g. environment, signal handlers +runner: sometimes may run for long 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! + +Why can't be NOEXEC: +suid: runs under different uid - must fork+exec + +Why shouldn't be NOFORK/NOEXEC: +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) + +[ - NOFORK +[[ - NOFORK +acpid - daemon +add-shell +addgroup +adduser +adjtimex +ar - runner +arch - NOFORK +arp +arping - runner +ash - interactive +awk - noexec, runner +base64 - runner +basename - NOFORK +beep +blkdiscard +blkid +blockdev +bootchartd - daemon +brctl +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 +clear - NOFORK +cmp - runner +comm - runner +conspy - interactive +cp - noexec, 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 +dhcprelay - daemon +diff - runner +dirname - NOFORK +dmesg +dnsd - daemon +dnsdomainname +dos2unix - noexec, runner +dpkg - runner +du +dumpkmap +dumpleases +echo - NOFORK +ed - interactive +egrep - runner +eject +env - noexec, changes state (env) +envdir - spawner +envuidgid - spawner +expand - runner +expr +factor - runner (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 +findfs - suid +flash_eraseall +flash_lock +flash_unlock +flashcp +flock +fold - noexec, runner +free +freeramdisk +fsck - interactive +fsck.minix +fsfreeze +fstrim +fsync - NOFORK +ftpd - daemon +ftpget - runner +ftpput - runner +fuser - complex +getopt +getty - interactive +grep - runner +groups - noexec +gunzip - runner +gzip - runner +halt - rare +hd - noexec, runner +hdparm - complex, rare +head - noexec, runner +hexdump - noexec, runner +hostid - NOFORK +hostname +httpd - daemon +hush - interactive +hwclock +i2cdetect +i2cdump +i2cget +i2cset +id - noexec +ifconfig +ifenslave +ifplugd - daemon +inetd - daemon +init - daemon +inotifyd - daemon +insmod +install - runner +ionice - spawner +iostat - runner +ip +ipaddr +ipcalc +ipcrm +ipcs +iplink +ipneigh +iproute +iprule +iptunnel +kbd_mode +kill +killall +killall5 +klogd - daemon +last +less - interactive +link - NOFORK +linux32 - spawner +linux64 - spawner +linuxrc - daemon +ln - noexec +loadfont +loadkmap +logger - runner +login - suid, interactive +logname - NOFORK +losetup - complex +lpd - daemon +lpq - runner +lpr - runner +ls - noexec, runner +lsattr +lsmod +lsof - complex +lspci +lsscsi +lsusb +lzcat - runner +lzma - runner +lzop - runner +lzopcat - runner +makedevs +makemime - runner +man - spawner, interactive +md5sum - noexec, runner +mdev - daemon +mesg +microcom - interactive, complex +mkdir - NOFORK +mkdosfs +mke2fs +mkfifo - noexec +mkfs.ext2 +mkfs.minix +mkfs.vfat +mknod - noexec +mkpasswd +mkswap +mktemp +modinfo +modprobe +more - interactive +mount - suid +mountpoint +mpstat +mt +mv +nameif +nbd-client +nc - runner +netstat +nice - spawner +nl - runner +nmeter - runner +nohup - spawner +nproc - NOFORK +ntpd - daemon +od - runner +openvt - spawner +partprobe +passwd - suid +paste - noexec, runner +patch +pgrep +pidof +ping - suid, runner +ping6 - suid, runner +pipe_progress +pivot_root +pkill +pmap +popmaildir - runner +poweroff - rare +powertop - interactive +printenv - NOFORK +printf - NOFORK +ps +pscan +pstree +pwd - NOFORK +pwdx +raidautorun +rdate +rdev +readlink +readprofile +realpath +reboot - rare +reformime - runner +remove-shell +renice +reset - spawner (execs "stty") +resize +rev - runner +rm - noexec, rm -i interactive +rmdir - NOFORK +rmmod +route +rpm - runner +rpm2cpio - runner +rtcwake - complex, rare +run-parts +runlevel +runsv - daemon +runsvdir - daemon +rx - runner +script +scriptreplay +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 +shred - runner +shuf - noexec, runner +slattach +sleep - runner +smemcap - runner +softlimit - spawner +sort - noexec, runner +split - runner +ssl_client - network +start-stop-daemon +stat +strings - runner +stty +su - suid, spawner +sulogin - spawner +sum - runner +sv +svc +svlogd - daemon +swapoff - rare +swapon - rare +switch_root - spawner, rare, change state +sync - NOFORK +sysctl +syslogd - daemon +tac - noexec, runner +tail - runner +tar - runner +taskset - spawner +tcpsvd - daemon +tee - runner +telnet - interactive +telnetd - daemon +test - NOFORK +tftp - runner +tftpd - daemon +time - spawner, change state (signals) +timeout - spawner, change state (signals) +top - interactive +touch - NOFORK +tr - runner +traceroute - suid, runner +traceroute6 - suid, runner +true - NOFORK +truncate - NOFORK +tty - NOFORK +ttysize +tunctl +tune2fs +ubiattach +ubidetach +ubimkvol +ubirename +ubirmvol +ubirsvol +ubiupdatevol +udhcpc - daemon +udhcpd - daemon +udpsvd - daemon +uevent - daemon +umount +uname - NOFORK +uncompress - runner +unexpand - runner +uniq - runner +unix2dos - noexec, runner +unlink - NOFORK +unlzma - runner +unlzop - runner +unxz - runner +unzip - runner +uptime +users +usleep - NOFORK +uudecode - runner +uuencode - runner +vconfig +vi - interactive +vlock - suid +volname - runner +w +wall - suid +watch - runner +watchdog - daemon +wc - runner +wget - runner +which - NOFORK +who +whoami - NOFORK +whois +xargs - noexec, spawner +xxd - noexec, runner +xz - runner +xzcat - runner +yes - noexec, runner +zcat - runner +zcip - daemon diff --git a/console-tools/clear.c b/console-tools/clear.c index 13eec498b..3cc16257b 100644 --- a/console-tools/clear.c +++ b/console-tools/clear.c @@ -12,7 +12,7 @@ //config: help //config: This program clears the terminal screen. -//applet:IF_CLEAR(APPLET(clear, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_CLEAR(APPLET_NOFORK(clear, clear, BB_DIR_USR_BIN, BB_SUID_DROP, clear)) //kbuild:lib-$(CONFIG_CLEAR) += clear.o diff --git a/coreutils/nproc.c b/coreutils/nproc.c index 68a831865..0ae55e70a 100644 --- a/coreutils/nproc.c +++ b/coreutils/nproc.c @@ -9,7 +9,7 @@ //config: help //config: Print number of CPUs -//applet:IF_NPROC(APPLET(nproc, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_NPROC(APPLET_NOFORK(nproc, nproc, BB_DIR_USR_BIN, BB_SUID_DROP, nproc)) //kbuild:lib-$(CONFIG_NPROC) += nproc.o diff --git a/coreutils/tty.c b/coreutils/tty.c index 331941a01..18ad7c566 100644 --- a/coreutils/tty.c +++ b/coreutils/tty.c @@ -13,7 +13,7 @@ //config: tty is used to print the name of the current terminal to //config: standard output. -//applet:IF_TTY(APPLET(tty, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_TTY(APPLET_NOFORK(tty, tty, BB_DIR_USR_BIN, BB_SUID_DROP, tty)) //kbuild:lib-$(CONFIG_TTY) += tty.o diff --git a/coreutils/uname.c b/coreutils/uname.c index aad58cab0..d6e447e33 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c @@ -63,9 +63,9 @@ //config: help //config: Same as uname -m. -//applet:IF_UNAME(APPLET(uname, BB_DIR_BIN, BB_SUID_DROP)) -// APPLET_ODDNAME:name main location suid_type help -//applet:IF_BB_ARCH(APPLET_ODDNAME(arch, uname, BB_DIR_BIN, BB_SUID_DROP, arch)) +// APPLET_NOFORK:name main location suid_type help +//applet:IF_UNAME(APPLET_NOFORK( uname, uname, BB_DIR_BIN, BB_SUID_DROP, uname)) +//applet:IF_BB_ARCH(APPLET_NOFORK(arch, uname, BB_DIR_BIN, BB_SUID_DROP, arch)) //kbuild:lib-$(CONFIG_UNAME) += uname.o //kbuild:lib-$(CONFIG_BB_ARCH) += uname.o diff --git a/coreutils/unlink.c b/coreutils/unlink.c index 3322d5b47..e32a9743c 100644 --- a/coreutils/unlink.c +++ b/coreutils/unlink.c @@ -11,7 +11,7 @@ //config: help //config: unlink deletes a file by calling unlink() -//applet:IF_UNLINK(APPLET(unlink, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_UNLINK(APPLET_NOFORK(unlink, unlink, BB_DIR_USR_BIN, BB_SUID_DROP, unlink)) //kbuild:lib-$(CONFIG_UNLINK) += unlink.o diff --git a/debianutils/which.c b/debianutils/which.c index 3197ddac1..b31d61871 100644 --- a/debianutils/which.c +++ b/debianutils/which.c @@ -12,7 +12,7 @@ //config: which is used to find programs in your PATH and //config: print out their pathnames. -//applet:IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which)) //kbuild:lib-$(CONFIG_WHICH) += which.o @@ -56,6 +56,8 @@ int which_main(int argc UNUSED_PARAM, char **argv) char *p; path = tmp = xstrdup(env_path); +//NOFORK FIXME: nested xmallocs (one is inside find_executable()) +//can leak memory on failure while ((p = find_executable(*argv, &tmp)) != NULL) { missing = 0; puts(p); -- cgit v1.2.3