$ mkdir mnt
$ bindfs /tmp mnt
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf
$ bindfs --no-allow-other /tmp mnt
$ mkdir /tmp/mnt2
$ bindfs --no-allow-other /tmp mnt/mnt2
fusermount: bad mount point /home/alan/mnt/mnt2: Permission denied
fusermount
falha porque é executado como um usuário diferente.
$ sudo ls mnt/
ls: cannot open directory 'mnt/': Permission denied
fusermount
é set-uid root
. Isso é necessário porque usuários sem privilégios não podem usar a mount()
chamada do sistema.
$ ls -l $(which fusermount)
-rwsr-xr-x. 1 root root 32848 Feb 7 2018 /usr/bin/fusermount
^ set-uid bit
E ainda. É relatado que o FUSE pode ser usado dentro de um diretório inicial do NFS. Mesmo que o diretório inicial tenha o modo 700
- acessível apenas pelo usuário proprietário. E o padrão do servidor NFS é root_squash
, o que significa que "o usuário root terá o mesmo acesso que o usuário none".
Por que esses dois casos diferem?
Estou testando no Fedora 28. Os relatórios sobre NFS são do Ubuntu 18.04. Essas distribuições são bastante semelhantes em idade, mas pode haver algumas diferenças.
Primeiro, considere a implementação de FUSE
no_allow_others
.Requer que todos os UIDs (IDs de usuário) efetivos, reais e salvos correspondam. (E o mesmo para GID). Isso é deliberadamente para impedir que um programa set-UID acesse a montagem.
https://github.com/torvalds/linux/blob/v4.18/fs/fuse/dir.c#L1024
Agora vamos rastrear o que
fusermount
faz. Podemos tentar olhare
O primeiro atinge um erro fatal "Permissão negada", porque o root set-UID não funciona ao executar em
strace
. O segundo é bem-sucedido, mas não pode mostrar parâmetros de string, como caminhos. Acho que os dois rastreamentos mostram o mesmo caminho de código geral até o erro fatal. Isso significa que podemos usar osstrace
resultados para preencher os parâmetros de string ausentes.Essa última chamada nos
strace
resultados é:Interessante!
"."
significa o diretório atual. Entãofusermount
já deve ter rodado no ponto de montagem... de alguma forma. Esse truque às vezes pode ser usado para acessar um diretório que você não pode acessar atualmente usando seu caminho absoluto.Se rolarmos para cima, podemos ver que
fusermount
realmente mudou para este diretório. E também estava dançando com algumas chamadas de sistema relacionadas a UID (e relacionadas a GID).Os resultados do UID estão "errados" na
strace
sessão. Podemos ver melhor a parte da dança do UID naperf trace
sessão. (Removi as colunas mais à esquerda para facilitar a leitura).As
setfsuid()
chamadas estão nas funçõesdrop_privs()
e em fusermount.c .restore_privs()
A
chdir()
chamada está escondida sorrateiramente na função chamadacheck_perm()
.Conclusão
Por que isso funciona no NFS? Resposta: porque o NFS examina o
fsuid
(efsgid
), que foi definido como o UID não raiz.Por que isso não funciona no FUSE, a menos que você tenha
allow_others
? Resposta: porque o FUSE verifica o UID "real", e não ofsuid
.