I was reading the famous Unix Recovery Legend, and it occurred to me to wonder:
If I had a BusyBox shell open, and the BusyBox binary were itself deleted, would I still be able to use all the commands included in the BusyBox binary?
Clearly I wouldn't be able to use the BB version of those commands from another running shell such as bash
, since the BusyBox file itself would be unavailable for bash
to open and run. But from within the running instance of BusyBox, it appears to me there could be two methods by which BB would run a command:
- It could fork and exec a new instance of BusyBox, calling it using the appropriate name—and reading the BusyBox file from disk to do so.
- It could fork and perform some internal logic to run the specified command (for example, by running it as a function call).
If (1) is the way BusyBox works, I would expect that certain BusyBox-provided commands would become unavailable from within a running instance of BB after the BB binary were deleted.
If (2) is how it works, BusyBox could be used even for recovery of a system where BB itself had been deleted—provided there were still a running instance of BusyBox accessible.
Is this documented anywhere? If not, is there a way to safely test it?
Best Answer
By default, BusyBox doesn't do anything special regarding the applets that it has built in (the commands listed with
busybox --help
).However, if the
FEATURE_SH_STANDALONE
andFEATURE_PREFER_APPLETS
options are enabled at compile time, then when BusyBox sh¹ executes a command which is a known applet name, it doesn't do the normalPATH
lookup, but instead runs its built-in applets through a shortcut:chgrp
,chmod
,chown
,cksum
,cp
,cut
,dd
,dos2unix
,env
,fold
,hd
,head
,hexdump
,ln
,ls
,md5sum
,mkfifo
,mknod
,sha1sum
,sha256sum
,sha3sum
,sha512sum
,sort
,tac
,unix2dos
.[[
,[
,basename
,cat
,dirname
,echo
,false
,fsync
,length
,logname
,mkdir
,printenv
,printf
,pwd
,rm
,rmdir
,seq
,sync
,test
,true
,usleep
,whoami
,yes
.fork
andexecve
), but instead of doing aPATH
lookup, BusyBox executes/proc/self/exe
, if available (which is normally the case on Linux), and a path defined at compile time otherwise.This is documented in a bit more detail in
docs/nofork_noexec.txt
. The applet declarations are ininclude/applets.src.h
in the source code.Most default configurations turn these features off, so that BusyBox executes external commands like any other shell. Debian turns these features on in both its
busybox
andbusybox-static
packages.So if you have a BusyBox executable compiled with
FEATURE_SH_STANDALONE
andFEATURE_PREFER_APPLETS
, then you can execute all BusyBox commands from a BusyBox shell even if the executable is deleted (except for the applets that are not listed above, if/proc/self/exe
is not available).¹ There are actually two implementations of "sh" in BusyBox — ash and hush — but they behave the same way in this respect.