O que mudou é que ele /bin/sh
se tornou bash
ou permaneceu, dash
recebendo uma bandeira adicional -p
imitando o comportamento do bash.
O Bash exige que o -p
sinalizador não elimine o privilégio setuid, conforme explicado em sua página de manual :
Se o shell for iniciado com o ID do usuário (grupo) efetivo diferente do ID do usuário (grupo) real e a opção -p não for fornecida, nenhum arquivo de inicialização será lido, as funções do shell não serão herdadas do ambiente, os SHELLOPTS As variáveis BASHOPTS, CDPATH e GLOBIGNORE, se aparecerem no ambiente, são ignoradas e o ID do usuário efetivo é definido como o ID do usuário real . Se a opção -p for fornecida na chamada, o comportamento de inicialização será o mesmo, mas o ID do usuário efetivo não será redefinido.
Antes, dash
não se importava com isso e permitia a execução de setuid (sem fazer nada para evitá-lo). Mas a página dash
de manual do Ubuntu 16.04 tem uma opção adicional descrita, semelhante a bash
:
-p priv
Não tente redefinir o uid efetivo se ele não corresponder ao uid. Isso não está definido por padrão para ajudar a evitar o uso incorreto de programas raiz setuid via system (3) ou popen (3).
Esta opção não existia no upstream (que pode não ter sido reativo a um patch proposto * ) nem no Debian 9, mas está presente no Debian buster que obteve o patch desde 2018.
OBSERVAÇÃO: conforme explicado por Stéphane Chazelas, é tarde demais para invocar "/bin/sh -p"
, system()
porque system()
executa qualquer coisa fornecida /bin/sh
e, portanto, o setuid já foi descartado. A resposta de derobert explica como lidar com isso, no código anterior system()
.
* mais detalhes sobre a história aqui e ali .
system("bash -p")
é executadosh -c "bash -p"
para que os privilégios já tenham sido eliminados quandobash
é executado.