Les commandes BusyBox sont-elles vraiment intégrées?

28

Je lisais la célèbre légende de récupération Unix , et je me suis demandé:

Si j'avais un shell BusyBox ouvert et que le binaire BusyBox était lui-même supprimé, serais-je toujours en mesure d'utiliser toutes les commandes incluses dans le binaire BusyBox?

De toute évidence, je ne serais pas en mesure d'utiliser la version BB de ces commandes d' un autre shell en cours d'exécution bash, car le fichier BusyBox lui-même ne serait pas disponible pour bashs'ouvrir et s'exécuter. Mais à partir de l'instance en cours d'exécution de BusyBox, il me semble qu'il pourrait y avoir deux méthodes par lesquelles BB exécuterait une commande:

  1. Il peut créer et exécuter une nouvelle instance de BusyBox, en l'appelant en utilisant le nom approprié et en lisant le fichier BusyBox à partir du disque.
  2. Il peut bifurquer et exécuter une logique interne pour exécuter la commande spécifiée (par exemple, en l'exécutant comme un appel de fonction).

Si (1) est la façon dont BusyBox fonctionne, je m'attendrais à ce que certaines commandes fournies par BusyBox deviennent indisponibles à partir d'une instance en cours d'exécution de BB après la suppression du binaire BB.

Si (2) fonctionne comme cela, BusyBox pourrait être utilisé même pour la récupération d'un système où BB lui-même avait été supprimé - à condition qu'il y ait toujours une instance en cours d'exécution de BusyBox accessible.

Est-ce documenté quelque part? Sinon, existe-t-il un moyen de le tester en toute sécurité?

Caractère générique
la source
2
is there a way to safely test it?Téléchargez l' openwrtimage générique x86 et attachez l'image à une nouvelle machine VirtualBox
bassin
2
Et cela soulève la question, comment les commandes Busybox continuent-elles de fonctionner après avoir PATHété désactivées? Suppose-t-il une valeur par défaut de PATH?
muru
2
@muru: D'après le code source (au moins pour son clone de cendres), il semble qu'il traite un PATH non défini de la même manière qu'une chaîne vide, il recherche donc le répertoire en cours, et seulement cela.
Henning Makholm
@HenningMakholm Eh bien, mon commentaire a été répondu par la réponse de Gilles. Cependant, il est bon de savoir que - je m'attendais à ce que seuls les buildins fonctionnent.
muru

Réponses:

33

Par défaut, BusyBox ne fait rien de spécial concernant les applets qu'il a intégrées (les commandes répertoriées avec busybox --help).

Cependant, si les options FEATURE_SH_STANDALONEet FEATURE_PREFER_APPLETSsont activées au moment de la compilation, alors lorsque BusyBox sh¹ exécute une commande qui est un nom d'applet connu, il ne fait pas la PATHrecherche normale , mais exécute à la place ses applets intégrées via un raccourci:

  • Les applets déclarées «noexec» dans le code source sont exécutées en tant qu'appels de fonction dans un processus forké. A partir de BusyBox 1,22, sont noexec les applets suivantes: 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 .
  • Les applets qui sont déclarées «nofork» dans le code source sont exécutées en tant qu'appels de fonction dans le même processus. A partir de BusyBox 1,22, les applets suivantes sont nofork: [[, [, basename, cat, dirname, echo, false, fsync, length, logname, mkdir, printenv, printf, pwd, rm, rmdir, seq, sync, test, true, usleep, whoami,yes .
  • D'autres applets sont réellement exécutées (avec forket execve), mais au lieu de faire une PATHrecherche, BusyBox s'exécute /proc/self/exe, si disponible (ce qui est normalement le cas sous Linux), et un chemin défini au moment de la compilation sinon.

Ceci est documenté un peu plus en détail dans docs/nofork_noexec.txt. Les déclarations d'applet sont include/applets.src.hdans le code source.

La plupart des configurations par défaut désactivent ces fonctionnalités, de sorte que BusyBox exécute des commandes externes comme tout autre shell. Debian active ces fonctionnalités dans ses packages busyboxet busybox-static.

Donc, si vous avez un exécutable BusyBox compilé avec FEATURE_SH_STANDALONEet FEATURE_PREFER_APPLETS, vous pouvez exécuter toutes les commandes BusyBox à partir d'un shell BusyBox même si l'exécutable est supprimé (à l'exception des applets qui ne sont pas répertoriées ci-dessus, si elles /proc/self/exene sont pas disponibles).

¹ Il existe en fait deux implémentations de "sh" dans BusyBox - ash et hush - mais elles se comportent de la même manière à cet égard.

Gilles 'SO- arrête d'être méchant'
la source
1
@Wildcard FEATURE_PREFER_APPLETSet FEATURE_SH_STANDALONEsont des indicateurs de compilation, activant ou désactivant des fonctionnalités. Les applets sont marquées noforket noexecquels que soient les drapeaux utilisés. Que ces marquages ​​aient ou non un effet dépend de FEATURE_PREFER_APPLETSleur activation. Par conséquent, trois comportements possibles: 1. FEATURE_PREFER_APPLETSdésactivé, 2. FEATURE_PREFER_APPLETSactivé et l'applet est nofork, 3. FEATURE_PREFER_APPLETSactivé et l'applet est noexec. Le troisième para dans la documentation l'explique bien. Et la dernière section montre les cas possibles.
muru
1
@Wildcard FEATURE_SH_STANDALONE(qui nécessite FEATURE_PREFER_APPLETS). noforkn'est pas nécessaire. Avec FEATURE_SH_STANDALONE, /proc/self/exeest utilisé le cas échéant, il fonctionnera donc même si BB a été supprimé . Vous pouvez tester cela avec un risque assez minime sur une Debian ou Arch Linux systm, exécutez busybox ash, unset PATH, faire les commandes de bassin. Ça fonctionne bien.
muru
3
Sur un système Ubuntu 14.04.1 LTS, Busybox est configuré pour préférer les applets. Puisque ni catne chmodnécessitent exec-ing un chemin, vous pouvez récupérer le fichier exécutable ainsi: cat /proc/self/exe > busybox; chmod 755 busybox.
Barefoot IO
1
@forest Il y a une énorme différence: tacnécessite soit un fichier d'entrée recherché qui n'est pas toujours disponible, soit la lecture de la totalité de l'entrée en mémoire. catpeut lire son entrée du début à la fin, en rejetant ce qui est déjà traité. Il est beaucoup plus facile à implémenter et il est également beaucoup plus couramment utilisé, il est donc plus logique d'optimiser celui-ci.
hvd
1
@Wildcard Nofork et noexec sont des indications définies sur chaque applet. FEATURE_xxxest une option de compilation pour BusyBox dans son ensemble. Les indications nofork et noexec n'ont d'importance que si elles FEATURE_PREFER_APPLETSsont actives (au moins dans le but d'exécuter une commande dans le shell, elles sont également utilisées dans d'autres contextes).
Gilles 'SO- arrête d'être méchant'
8

is there a way to safely test it? Avec l'image générique x86 openwrt:

capture d'écran vbox

La plupart des commandes ne sont pas intégrées, mais certaines le sont, comme echoet printf. Un fichier binaire avec un contenu arbitraire peut être créé en utilisant printf, mais chmod +xsera un problème.

bassin
la source
Intéressant; exécutez-vous cela à partir de BusyBox lui-même, ou d'un autre shell?
Wildcard
4
(En outre, cela vous dérangerait-il de coller dans le texte plutôt qu'une capture d'écran?)
Wildcard
@Wildcard /bin/ash -> busybox.
bassin
1
Comme dans la réponse de Gilles, si FEATURE_SH_STANDALONEest activé, vous n'obtiendrez pas ce comportement. Le second mvfonctionnera parfaitement bien.
muru