Bem, esta foi uma experiência de aprendizado para mim, mas acabei descobrindo. Vou explicar meu processo aqui para que seja mais fácil saber como resolver isso sozinho (a documentação do BTRFS, como tenho certeza que você descobriu, está relativamente incompleta por enquanto).
No começo, pensei que criar o subvolume era um ioctl
com um manipulador que não fazia nenhuma verificação de capacidade (que pode ou não ter sido um problema de segurança dependendo se havia alguma lógica nele), enquanto a exclusão ele estava modificando os metadados diretamente (e, portanto, o usuário pode exigir que CAP_SYS_RAWIO
funcione corretamente).
Para verificar, eu abri o código-fonte btrfs-utils
e foi isso que encontrei:
Create subvolume, cmds-receive.c Line 180:
ret = ioctl(r->dest_dir_fd, BTRFS_IOC_SUBVOL_CREATE, &args_v1);
Delete subvolume, cmds-subvolume.c Line 259:
res = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
Bem, isso não é útil, eles são ambos ioctl's (nota interessante: "snapshot" é freqüentemente usado de forma intercambiável no código fonte com "subvolume" por algum motivo). Então eu fui ao código-fonte do kernel e encontrei os dois manipuladores em fs/btrfs/ioctl.c
.
Eventualmente, eu o rastreei de volta para btrfs_ioctl_snap_destroy()
e na linha 2116:
if (!capable(CAP_SYS_ADMIN)){
Especificamente, esta é uma verificação se eles não têm a capacidade, mas se eles o tiverem, a lógica irá direto para a execução da operação. O corpo da instrução if verifica se é o usuário regular quem é o proprietário do inode do subvolume e se a opção USER_SUBVOL_RM_ALLOWED
BTRFS está habilitada para continuar executando o manipulador. Se eles não tiverem o manipulador ioctl, haverá um erro.
Portanto, parece que destruir um "instantâneo" (também conhecido como "subvolume") geralmente requer um usuário que tenha CAP_SYS_ADMIN
(ou que USER_SUBVOL_RM_ALLOWED
esteja habilitado e que o usuário "possua" o subvolume fornecido). Ótimo, que tal criar um instantâneo / volume?
O manipulador para o ioctl parece ser btrfs_ioctl_snap_create()
. Esse manipulador parece não conter nenhuma chamada para capable()
direta ou indiretamente. Como essa é a principal maneira de acesso é intermediado, estou tomando isso como significando que a criação de subvolume sempre é bem-sucedida. Isso explica em um nível funcional porque você está vendo o que está vendo.
Eu não posso falar com porque isso é considerado desejável fora do principal caso de uso do BTRFS estar com um servidor com acesso de usuário restrito. Isso não é suficiente, mas não estou vendo nenhum código para interromper a operação. Se você não consegue encontrar uma resposta do porquê (e você se importa em tê-lo), você pode ter que perguntar na lista de discussão do kernel.
Conclusão
Minha pesquisa parece indicar que qualquer pessoa pode criar subvolumes, mas para excluir um subvolume, é necessário ter CAP_SYS_ADMIN
ou é necessário que o usuário chamador seja o proprietário do inode de subvolume e USER_SUBVOL_RM_ALLOWED
ativado.
A criação de subvolume não faz sentido, então provavelmente estou perdendo alguma forma indireta de a operação ser negada, já que parece ser uma maneira fácil de fazer DoS um sistema.
Observação: não estou em um local em que possa verificar essa funcionalidade, mas quando chegar em casa, posso definir se setcap
magic funciona como isso é previsto.