Команды BusyBox действительно встроены?

28

Я читал знаменитую легенду восстановления Unix , и мне пришло в голову удивление:

Если бы у меня была открыта оболочка BusyBox, а двоичный файл BusyBox был удален сам, смогу ли я по-прежнему использовать все команды, включенные в двоичный файл BusyBox?

Ясно, что я не смог бы использовать версию BB этих команд из другой запущенной оболочки, например bash, так как сам файл BusyBox был бы недоступен для bashоткрытия и запуска. Но из запущенного экземпляра BusyBox, мне кажется, может быть два метода, с помощью которых BB будет выполнять команду:

  1. Он может создать и выполнить новый экземпляр BusyBox, вызвав его с использованием соответствующего имени и прочитав для этого файл BusyBox с диска.
  2. Он может выполнить разветвление и выполнить некоторую внутреннюю логику для запуска указанной команды (например, запустив ее как вызов функции).

Если (1) работает BusyBox, я ожидаю, что некоторые команды, предоставленные BusyBox, станут недоступными из запущенного экземпляра BB после удаления двоичного файла BB.

Если (2) работает так, BusyBox можно использовать даже для восстановления системы, в которой был удален сам BB - при условии, что все еще доступен работающий экземпляр BusyBox.

Это где-нибудь задокументировано? Если нет, есть ли способ безопасно проверить это?

Wildcard
источник
2
is there a way to safely test it?Загрузите общий openwrtобраз x86 и прикрепите его к новой машине VirtualBox
таз
2
И это поднимает вопрос, как команды Busybox продолжают работать после PATHсброса? Это принимает значение по умолчанию PATH?
Муру
2
@muru: Исходный код (по крайней мере, для его клона ash) выглядит так, как будто он обрабатывает неустановленную переменную PATH так же, как и пустую строку, поэтому он ищет текущий каталог и только его.
Хеннинг Махолм
@HenningMakholm Ну, на мой комментарий ответил ответ Жиля. Тем не менее, это хорошо знать - я ожидал, что будут работать только встроенные функции.
Муру

Ответы:

33

По умолчанию BusyBox не делает ничего особенного в отношении встроенных апплетов (команды указаны с помощью busybox --help).

Однако, если FEATURE_SH_STANDALONEи FEATURE_PREFER_APPLETSопции включены во время компиляции, а затем , когда BusyBox sh¹ выполняет команду , которая является известным апплетом имени, он не делает нормальный PATHпоиск, но вместо этого запускает встроенный в апплетах через ярлык:

  • Апплеты, которые объявлены как «noexec» в исходном коде, выполняются как вызовы функций в разветвленном процессе. По состоянию BusyBox 1,22, следующие апплеты поехес: 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.
  • Апплеты, которые объявлены как «nofork» в исходном коде, выполняются как вызовы функций в том же процессе. По состоянию BusyBox 1,22, следующие апплеты nofork: [[, [, basename, cat, dirname, echo, false, fsync, length, logname,mkdir , printenv, printf, pwd, rm, rmdir, seq, sync, test, true, usleep, whoami, yes.
  • Другие апплеты действительно выполняются (с помощью forkи execve), но вместо PATHпоиска выполняется BusyBox /proc/self/exe, если он доступен (что обычно имеет место в Linux), и путь, определенный во время компиляции в противном случае.

Это задокументировано более подробно в docs/nofork_noexec.txt. Объявления апплета находятся в include/applets.src.hисходном коде.

В большинстве конфигураций по умолчанию эти функции отключены, поэтому BusyBox выполняет внешние команды, как и любая другая оболочка. Debian включает эти функции как в своих, так busyboxи в busybox-staticпакетах.

Таким образом, если у вас есть исполняемый файл BusyBox, скомпилированный с FEATURE_SH_STANDALONEи FEATURE_PREFER_APPLETS, то вы можете выполнить все команды BusyBox из оболочки BusyBox, даже если исполняемый файл удален (за исключением апплетов, которые не перечислены выше, если они /proc/self/exeнедоступны).

¹ На самом деле в BusyBox есть две реализации «sh» - ash и hush - но они ведут себя одинаково в этом отношении.

Жиль "ТАК - перестань быть злым"
источник
1
@Wildcard FEATURE_PREFER_APPLETSи FEATURE_SH_STANDALONEфлаги времени компиляции, включающие или отключающие функции. Апплеты помечены noforkи noexecнезависимо от того, какие флаги были использованы. Будет ли такая маркировка иметь какой-либо эффект, зависит от FEATURE_PREFER_APPLETSтого, включена ли она. Следовательно, три возможных поведения: 1. FEATURE_PREFER_APPLETSотключен, 2. FEATURE_PREFER_APPLETSвключен и апплет nofork, 3. FEATURE_PREFER_APPLETSвключен и апплет noexec. Третий параграф в документации объясняет это хорошо. И последний раздел показывает возможные случаи.
Муру
1
@Wildcard FEATURE_SH_STANDALONE(которая требует FEATURE_PREFER_APPLETS). noforkне нужен С FEATURE_SH_STANDALONE, /proc/self/exeиспользуется там, где это применимо, поэтому он будет работать, даже если BB был удален . Вы можете проверить это с довольно минимальным риском на любом Debian или Arch Linux systm, запуска busybox ash, unset PATHвыполните команды Басина. Работает нормально.
Муру
3
В системе Ubuntu 14.04.1 LTS Busybox настроен на использование апплетов. Поскольку ни catни chmodне требует Exec-кий путь к файлу, вы можете восстановить исполняемый файл таким образом: cat /proc/self/exe > busybox; chmod 755 busybox.
Босиком IO
1
@forest Существует огромная разница: tacтребуется либо доступный для поиска входной файл, который не всегда доступен, либо чтение всего ввода в память. catможет прочитать его ввод от начала до конца, отбрасывая то, что он уже обработал. Его гораздо проще реализовать, и он также гораздо чаще используется, поэтому имеет смысл оптимизировать его.
HVd
1
@Wildcard Nofork и noexec - это индикации, установленные для каждого апплета. FEATURE_xxxопция компиляции для BusyBox в целом Указания nofork и noexec имеют значение только в том случае, если они FEATURE_PREFER_APPLETSактивны (по крайней мере, для выполнения команды в оболочке они также используются в некоторых других контекстах).
Жиль "ТАК - перестань быть злым"
8

is there a way to safely test it? С помощью общего образа x86 openwrt:

скриншот vbox

Большинство команд не являются встроенными, но некоторые, как echoи printf. Бинарный файл с произвольным содержимым может быть создан с использованием printf, но chmod +xэто будет проблемой.

бассейн
источник
Интересный; Вы запускаете это изнутри самого BusyBox или какой-то другой оболочки?
Wildcard
4
(Кроме того, не могли бы вы вставить текст, а не скриншот?)
Wildcard
@Wildcard /bin/ash -> busybox.
бассейн
1
Как и в ответе Жиля, если FEATURE_SH_STANDALONEвключено, вы не получите такое поведение. Второй mvбудет работать отлично.
Муру