Encontrei algum comportamento surpreendente no Ubuntu 14.04 ao usar strace
um executável, no qual não tenho permissão de leitura. Gostaria de saber se isso é um bug ou se algum padrão exige esse comportamento obscuro.
Primeiro vamos ver o que acontece quando inicio um executável comum em segundo plano e o anexo a ele. Como esperado, isso funciona:
$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>
Em seguida, tento com um executável, no qual não tenho permissão de leitura:
---x--x--x 1 root root 26280 Sep 3 09:37 sleep*
Anexar a este processo em execução não é permitido:
$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
Isso também é o que eu esperaria. Conceder permissão de execução sem permissão de leitura não faria muito bem, se eu pudesse simplesmente anexar um depurador ao processo e efetivamente ter permissões de leitura no executável dessa maneira.
Mas se eu iniciar o executável em um processo já rastreado, tenho permissão para fazê-lo:
$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0) = 0x9b7a000
Isso é inesperado para mim. Isso é um bug de segurança ou é um recurso exigido por um padrão?
fonte
execve
chamadas, as permissões de leitura do arquivo executado não são verificadas novamente se o processo já estiver rastreado. Sua pergunta é se isso é um bug de segurança ou um recurso obrigatório (se este último, eu ainda consideraria um bug de segurança, apenas um bug de segurança da especificação).EPERM
parece vir deget_dumpable()
(usado também para verificar se o dumping núcleo é permitido, portanto, "dumpable") chamado a partir__ptrace_may_access()
chamado deptrace_attach()
onkernel/ptrace.c
.Respostas:
Esta não é uma resposta, mas uma coleção de links e pensamentos, caso outra pessoa também queira estudar. Porque isso é uma coisa bastante interessante.
Resposta relacionada no Unix e Linux mencionando que é (ou foi, não é possível testar com o kernel da baunilha agora) possível despejar binários somente leitura dessa maneira.
O Grsecurity estava tentando corrigir esta opção de configuração e o próprio patch (embora possa ter sido alterado desde então)
Esse commit realmente faz parecer que, os desenvolvedores do kernel realmente se preocupam apenas com o despejo de binários suid.
Mas, a partir dessa linha, eu acho que o kernel quer impedir o despejo de binários ilegíveis em relação ao status do SUID. E essa linha sugere que os binários que não são despejáveis não devem ser rastreáveis.
Então, à primeira vista, parece que você encontrou um bug no kernel com implicações de segurança. Mas eu não sou desenvolvedor de kernel, então não posso dizer com certeza. Eu perguntaria no LKML.
Edit: mais uma descoberta, com relação ao depurador, mencionada nos comentários da postagem original - do rastreamento rápido (novamente) me parece que o gdb usa os binários rastreados e
/proc/<pid>/mem
. Quando o binário em execução não estiver legível,cat /proc/<pid>/mem
retornaráEPERM
. Se o binário estiver legível, ele retornaráEIO
. (Testei isso no Ubuntu 14.10, que executa várias correções de segurança, portanto, isso pode ser diferente do kernel da baunilha. Novamente, não tenho o kernel da baunilha sendo executado em qualquer lugar útil :()fonte