Perder permissões adicionando capacidade?

6

Eu observei o seguinte fenómeno que não consigo explicar. Depois de adicionar o recurso CAP_SYS_ADMIN , unshare não poderá mais gravar em /proc/self/setgroups .

De fato, gravar neste arquivo requer a capacidade, mas isso é obtido alterando o namespace do usuário. Então, por que a adição da capacidade ao processo pai impede a gravação neste arquivo?

me@myhost:~$ unshare -r
root@myhost:~# exit
logout

me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied

me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#

A propósito: Estou executando o Ubuntu 16.04.4 LTS com a versão 4.4 do kernel e a versão do util-linux (incluindo unshare ) é 2.27.1.

    
por koalo 19.07.2018 / 22:36

1 resposta

8

O que está acontecendo aqui é que o processo de "compartilhamento não compartilhado" não tem acesso para gravar nos arquivos setgroups (e uid_maps , gid_maps ) no namespace de usuário external .

Nesse namespace, os pseudo-arquivos em /proc/<PID> serão de propriedade da raiz e, como se o seu uid efetivo ainda fosse seu próprio usuário, você não terá acesso para gravar nesses arquivos.

Você pode visualizar isso facilmente executando um processo em segundo plano (como sleep ) e inspecionando as permissões do arquivo setgroups enquanto ele está em execução ( uid_maps e gid_maps se comportam exatamente da mesma forma.)

Primeiro, com um binário que não tenha recursos adicionais:

$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+  Done                    ./sleep 10
$

Então, vamos adicionar alguns recursos de arquivo a ele e ver a alteração de propriedade:

$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups 
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+  Done                    ./sleep 10
$

A propriedade dos arquivos em /proc/<PID> é controlada pelo sinalizador "dumpable" dentro do kernel Linux, que é usado para evitar vazamento de informações de um processo privilegiado para um usuário sem privilégios.

E considerando que você está executando unshare com recursos adicionais, mas ainda com um eficaz uid não-root, o acesso de gravação a esses pseudo-arquivos que são de propriedade do root é impedido através do acesso normal controles do sistema operacional.

Você pode inspecionar o valor do sinalizador "dumpable" usando o comando PR_GET_DUMPABLE do prctl (2) syscall.

Na descrição de PR_SET_DUMPABLE , você também encontrará:

Normally, this flag is set to 1. However, it is reset to the current value contained in the file /proc/sys/fs/suid_dumpable (which by default has the value 0), in the following circumstances:

[...]

  • The process executes (execve(2)) a program that has file capabilities (see capabilities(7)), but only if the permitted capabilities gained exceed those already permitted for the process.

Qual é exatamente o seu caso, com um binário unshare que possui recursos de arquivo.

Curiosamente, usar um binário setuid de propriedade root para unshare não é executado exatamente nesse problema. Sim, limpará os sinalizadores "dumpable" e os arquivos em /proc/<PID> serão de propriedade de root. Mas considerando seu uid efetivo é também root ao executar um binário setuid, o acesso será permitido.

Nesse caso, você acaba encontrando um problema diferente, que tem a ver com a lógica de unshare não ser capaz de lidar com essa configuração específica (provavelmente algo a ver com o uid efetivo e o uid real não correspondendo ):

$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$ 

Observe também que a limpeza do sinalizador "dumpable" foi acionada pela execução de um binário com recursos de arquivo definidos. Se você obtiver recursos adicionais de uma maneira diferente, talvez não se depare com esse problema. Por exemplo, usar recursos de "ambiente" é uma boa maneira de obter recursos adicionais fora do espaço de nomes, embora ainda não tenha problemas ao não compartilhar um novo namespace de usuário.

(infelizmente, ainda não há muitas ferramentas em torno dos recursos do ambiente. libcap envia somente o suporte no git mais recente, a versão passada 2.25, que é atualmente enviada na maioria das distros. capsh é de nível razoavelmente baixo , por isso não é tão fácil fazer isso certo. Veja aqui para detalhes sobre como usar o mais recente capsh para adicionar Também tentei systemd-run , mas realmente não consegui ter recursos de ambiente configurados. De qualquer forma, algo para você pesquisar, se você precisar de recursos, namespaces de usuário e de usuário não-root juntos!)

    
por 31.07.2018 / 22:03