Os comandos do BusyBox são realmente integrados?

28

Eu estava lendo a famosa lenda do Unix Recovery , e me ocorreu pensar:

Se eu tivesse um shell do BusyBox aberto e o próprio binário do BusyBox fosse excluído, ainda seria possível usar todos os comandos incluídos no binário do BusyBox?

Claramente, eu não seria capaz de usar a versão BB desses comandos de outro shell em execução, como bash, uma vez que o próprio arquivo BusyBox não estaria disponível para bashabrir e executar. Mas, a partir da instância em execução do BusyBox, parece-me que poderia haver dois métodos pelos quais o BB executaria um comando:

  1. Ele poderia bifurcar e executar uma nova instância do BusyBox, chamando-a usando o nome apropriado - e lendo o arquivo BusyBox do disco para fazer isso.
  2. Ele poderia bifurcar e executar alguma lógica interna para executar o comando especificado (por exemplo, executando-o como uma chamada de função).

Se (1) for o modo como o BusyBox funciona, eu esperaria que determinados comandos fornecidos pelo BusyBox fiquem indisponíveis a partir de uma instância em execução do BB após a exclusão do binário do BB.

Se (2) é assim que funciona, o BusyBox pode ser usado até para recuperar um sistema em que o próprio BB foi excluído - desde que ainda exista uma instância em execução do BusyBox acessível.

Isso está documentado em algum lugar? Caso contrário, existe uma maneira de testá-lo com segurança?

Curinga
fonte
2
is there a way to safely test it?Baixe o x86 genérico openwrtimagem e anexar a imagem para uma nova máquina VirtualBox
bacia
2
E isso levanta a questão: como os comandos do Busybox continuam a funcionar após a PATHdesativação? Ele assume um valor padrão de PATH?
Muru
2
@ muru: A partir do código-fonte (pelo menos para o seu clone do ash), parece que ele trata um PATH não definido da mesma forma que faria com uma string vazia, por isso pesquisa no diretório atual e somente isso.
Henning Makholm
@ HenningMakholm Bem, meu comentário foi respondido pela resposta de Gilles. No entanto, é bom saber disso - eu esperava que apenas os componentes internos funcionassem.
Muru

Respostas:

33

Por padrão, o BusyBox não faz nada de especial em relação aos applets incorporados (os comandos listados busybox --help).

No entanto, se as opções FEATURE_SH_STANDALONEe FEATURE_PREFER_APPLETSestiverem ativadas no momento da compilação, quando o BusyBox executar um comando que é um nome conhecido de applet, ele não fará a PATHpesquisa normal , mas executará seus applets internos por meio de um atalho:

  • Os applets declarados como "noexec" no código-fonte são executados como chamadas de função em um processo bifurcado. A partir de 1,22 BusyBox, os seguintes applets são noexec: 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.
  • Os applets declarados como "nofork" no código-fonte são executados como chamadas de função no mesmo processo. A partir de 1,22 BusyBox, os seguintes applets são nofork: [[, [, basename, cat, dirname, echo, false, fsync, length, logname, mkdir, printenv, printf, pwd, rm, rmdir, seq, sync, test, true, usleep, whoami, yes.
  • Outros applets são realmente executados (com forke execve), mas, em vez de fazer uma PATHpesquisa, o BusyBox executa /proc/self/exe, se disponível (o que normalmente acontece no Linux), e um caminho definido no momento da compilação.

Isso está documentado com mais detalhes em docs/nofork_noexec.txt. As declarações do applet estão no include/applets.src.hcódigo-fonte.

A maioria das configurações padrão desativa esses recursos, para que o BusyBox execute comandos externos como qualquer outro shell. O Debian ativa esses recursos nos pacotes its busyboxebusybox-static

Portanto, se você tiver um executável do BusyBox compilado com FEATURE_SH_STANDALONEe FEATURE_PREFER_APPLETS, poderá executar todos os comandos do BusyBox a partir de um shell do BusyBox, mesmo que o executável seja excluído (exceto os applets que não estão listados acima, se /proc/self/exenão estiver disponível).

¹ Na verdade, existem duas implementações de "sh" no BusyBox - cinzas e silêncio - mas eles se comportam da mesma maneira a este respeito.

Gilles 'SO- parar de ser mau'
fonte
1
@Wildcard FEATURE_PREFER_APPLETSe FEATURE_SH_STANDALONEsão sinalizadores de tempo de compilação, ativando ou desativando recursos. Os applets estão marcados noforke noexecindependentemente de quais sinalizadores foram usados. Se essas marcações têm ou não efeito, depende da FEATURE_PREFER_APPLETSativação. Portanto, três comportamentos possíveis: 1. FEATURE_PREFER_APPLETSdesativado, 2. FEATURE_PREFER_APPLETSativado e com applet nofork, 3. FEATURE_PREFER_APPLETSativado e com applet noexec. O terceiro parágrafo na documentação explica bem. E a última seção mostra os casos possíveis.
Muru
1
@Wildcard FEATURE_SH_STANDALONE(que requer FEATURE_PREFER_APPLETS). noforknão é necessário. Com FEATURE_SH_STANDALONE, /proc/self/exeé usado onde aplicável, portanto, ele funcionará mesmo que o BB tenha sido excluído . Você pode testar isso com o risco bastante mínimo em qualquer systm Debian ou Arch Linux, run busybox ash, unset PATH, faça comandos da bacia. Funciona bem.
Muru
3
Em um sistema Ubuntu 14.04.1 LTS, o Busybox é configurado para preferir applets. Uma vez que nem catnem chmodexigem exec-ing um caminho, você pode recuperar o executável assim: cat /proc/self/exe > busybox; chmod 755 busybox.
Barefoot IO
1
@forest Há uma enorme diferença: tacrequer um arquivo de entrada pesquisável que nem sempre está disponível ou a leitura de toda a entrada na memória. catpode ler sua entrada do início ao fim, descartando o que já foi processado. É muito mais fácil de implementar e também é muito mais usado, por isso faz mais sentido otimizar esse.
Hv
1
@Wildcard Nofork e noexec são indicações definidas em cada applet. FEATURE_xxxé uma opção em tempo de compilação para o BusyBox como um todo. As indicações nofork e noexec importam apenas se FEATURE_PREFER_APPLETSestiverem ativas (pelo menos com a finalidade de executar um comando no shell, elas também são usadas em outros contextos).
Gilles 'SO- stop being evil'
8

is there a way to safely test it? Com a imagem openwrt genérica x86:

captura de tela do vbox

A maioria dos comandos não é incorporada, mas alguns são, como echoe printf. Um arquivo binário com conteúdo arbitrário pode ser criado usando printf, mas chmod +xserá um problema.

bacia
fonte
Interessante; você está executando isso no próprio BusyBox ou em algum outro shell?
Curinga
4
(Além disso, você se importaria de colar no texto, em vez de uma imagem?)
Wildcard
@Wildcard /bin/ash -> busybox.
bacia
1
Como na resposta de Gilles, se FEATURE_SH_STANDALONEestiver ativado, você não receberá esse comportamento. O segundo mvfuncionará perfeitamente bem.
Muru