Se o arquivo for um arquivo de texto simples criado pelo root com:
echo 'foo' > ./file.txt
O seu ls -l
é:
-rw-r--r-- root root ./file.txt
Mas como um usuário comum, posso mudar isso salvando o vim com :w!
ou com um comando sed e quando isso acontece o usuário e grupo que possui este arquivo é alterado para:
-rw-r--r-- user user ./file.txt
Depois percebi que quando removido outros leram permissão com chmod o-r ./file.txt
não consigo mais fazer as alterações, mas quando restaurado com chmod o+r ./file.txt
consigo novamente.
O que esta acontecendo aqui? Por que a permissão de leitura "outros" me permite alterar um arquivo de propriedade do root e também alterar a propriedade do usuário e do grupo?
Por que isso está acontecendo?
PS: Eu uso o Debian SID.
Isso está acontecendo por causa de duas coisas:
vim
(pelo menos neste caso) esed
, ao fazer a edição no local, exclua o arquivo original e crie um novo com o mesmo nome.a capacidade de excluir um arquivo depende das permissões do diretório que contém o arquivo, e não das permissões do arquivo em si.
Então, o que está acontecendo aqui é que você tem permissão de gravação no diretório, o que significa que você pode alterar o conteúdo do diretório, incluindo excluir e criar arquivos. Portanto, quando você executa
sed -i
ou salva com:w!
, você está excluindo o original e criando um novo arquivo. É também por isso que a propriedade muda: na verdade, este é um arquivo diferente.Você pode demonstrar isso verificando o inode do arquivo antes e depois da edição:
Após esses comandos, tenho
file
, de propriedade do root, no diretóriofoo/
no qual meu usuário regular tem permissão de gravação. Agora, vamosls -i
verificar o inode e, em seguida, fazer uma alteraçãosed
e verificar novamente:Você também pode ver
vim
fazendo a mesma coisa executandoEm seguida, edite o arquivo e salve com a extensão
:w!
. No seustrace.out
, você verá:Então, primeiro o arquivo foi excluído (
unlink("file")
), depois foi criado um novo arquivo com o mesmo nome (open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)
) e nele foram gravadas as modificações que eu havia feito (write(4, "bar\n", 11)
).Como você pode ver acima, o inode mudou: este é um novo arquivo com o mesmo nome. Então você não alterou realmente um arquivo ao qual não tinha acesso de gravação, você alterou um diretório ao qual tinha acesso de gravação excluindo um arquivo nesse diretório e criando um novo arquivo no diretório com o mesmo nome que o antigo.
Eu respondi a uma pergunta semelhante aqui: https://askubuntu.com/a/815849/85695 .
vim
não pode modificar o arquivo, mas se tiver acesso de gravação ao diretório ao qual o arquivo está vinculado e ot
bit não estiver definido para esse diretório, ele poderá excluí-lo e substituí-lo por uma nova cópia de sua propriedade.Para evitar isso,
root
podeimmutable
(chattr +i
) ouappend-only
(chattr +a
) no arquivo (entãoroot
não será possível excluí-lo)root
tenha acesso de gravação ao diretório pai¹ (de propriedaderoot
ew
bit apenas para o usuário;chown root:
,chmod u=rwx,go=rx
)root
, possivelmente gravável por outros, mas ter ot
bit (de exclusão restrita²) (chmod o+t
) nas permissões (para que os usuários possam excluir/renomear apenas os arquivos de sua propriedade).¹ Esteja ciente de que, para um arquivo chamado
/a/b/file
ifuser
tem acesso de gravação/a
, então também pode renomear/a/b
e/a/b.old
recriar um/a/b
arquivo/a/b/file
próprio dentro dele.² você pode ter ouvido o termo sticky bit para esse bit, mas é quando aplicado a arquivos executáveis regulares (e apenas em sistemas muito antigos), onde instrui (usado para instruir) o sistema a manter o texto do executável na memória. Quando aplicado a um diretório, esse bit tem um significado diferente e não relacionado.