Eu crio um arquivo como usuário regular testuser
:
$ cat > /tmp/zz
o arquivo é de propriedade desse usuário (como esperado):
$ ls -lA /tmp/zz
-rw------- 1 testuser testuser 0 Feb 20 15:32 zz
Agora, quando tento truncá-lo como root
, recebo permissão negada:
# truncate --size=0 /tmp/zz
truncate: cannot open '/tmp/zz' for writing: Permission denied
Quando tento com strace
, vejo o seguinte:
openat(AT_FDCWD, "/tmp/zz", O_WRONLY|O_CREAT|O_NONBLOCK, 0666) = -1 EACCES (Permission denied)
write(2, "truncate: ", 10truncate: ) = 10
write(2, "cannot open '/tmp/zz' for writin"..., 33cannot open '/tmp/zz' for writing) = 33
...
write(2, ": Permission denied", 19: Permission denied) = 19
write(2, "\n", 1
Por que o root não tem permissão para gravar nesse arquivo? Root pode deletar o arquivo, mas não escrever.
Este é um novo comportamento disponível nos kernels do Linux desde a versão 4.19 para evitar ataques usando
/tmp/
truques. O valor padrão da opção pode ter sido ativado posteriormente ou ser diferente dependendo da distribuição.Isso se destina a proteger um usuário (incluindo o root que normalmente sempre tem privilégios suficientes) para gravar em um arquivo preexistente em um diretório como
/tmp
ou/var/tmp
enquanto ele pretendia criá-lo.É ativado com esta
sysctl
alternância:fs.protected_regular
. Pode-se reverter ao comportamento anterior com:mas isso provavelmente diminuirá a segurança geral, enquanto faz com que alguns "bugs" estranhos, como o caso do OP, desapareçam.
Quanto ao motivo pelo qual o root ainda pode excluir o arquivo, é porque o recurso de segurança adicional é acionado apenas para abrir um arquivo para gravação, não para desvinculá-lo:
truncate -s ...
abre o arquivo para gravação,rm
não (usaunlink
ouunlinkat
).