Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | 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 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 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); 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 - noexec. leaks: open+xfunc addgroup - noexec. leaks adduser - noexec. leaks adjtimex - NOFORK ar - runner arch - NOFORK arp - talks to network: arp -n queries DNS arping - longterm ash - interactive, longterm awk - noexec. runner base64 - runner basename - NOFORK beep - longterm: beep -r 999999999 blkdiscard - noexec. leaks: open+xioctl blkid - noexec blockdev - noexec. leaks fd bootchartd - daemon brctl - noexec bunzip2 - runner bzcat - runner bzip2 - 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, longterm cp - noexec. sometimes 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 - 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 - runner dnsd - daemon 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 - noexec. leaks: open+xread echo - NOFORK 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 - noexec. leaks: nested allocs factor - longterm (eats stdin if no params) fakeidentd - daemon false - NOFORK 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 - 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 - 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 - hardware head - noexec. runner hexdump - noexec. runner hexedit - interactive, longterm hostid - NOFORK hostname - noexec. talks to network (hostname -d may query DNS) httpd - daemon hush - interactive, longterm hwclock - hardware (xioctl(RTC_RD_TIME)) i2cdetect - hardware i2cdump - hardware i2cget - hardware i2cset - hardware id - noexec 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 - noexec install - runner 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 - 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 - 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, longterm logname - NOFORK losetup - noexec. 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 - noexec makemime - runner man - spawner, interactive, longterm md5sum - noexec. runner mdev - daemon mesg - NOFORK microcom - interactive, longterm minips - noexec 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 - hardware mv - noexec. sometimes runner nameif - noexec. openlog(), leaks: config_open2+ioctl_or_perror_and_die nbd-client - noexec nc - runner 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 - 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, longterm printenv - NOFORK printf - NOFORK ps - noexec pscan - talks to network pstree - noexec pwd - NOFORK 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 - 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 - 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 - 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 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 - 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 - 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 sulogin - noexec. spawner sum - runner sv - noexec. needs ^C (uses usleep(420000)) svc - noexec. needs ^C (uses usleep(420000)) svlogd - daemon 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 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, longterm traceroute6 - suid, longterm true - NOFORK truncate - NOFORK tty - NOFORK 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 - 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 - 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 - noexec. leaks: xsocket+ioctl_or_perror_and_die vi - interactive, longterm vlock - suid 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 - noexec. nofork candidate(is getutxent ok?) whoami - NOFORK whois - talks to network xargs - noexec. spawner xxd - noexec. runner xz - runner xzcat - runner yes - noexec. runner zcat - runner zcip - daemon |