Por que um arquivo com 400 permissões é gravável pelo root, mas somente leitura pelo usuário?

10

Se eu criar um arquivo como um usuário não privilegiado e alterar o modo de permissões para 400, ele será visto como somente leitura, corretamente:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

Tudo está bem.

Mas então a raiz aparece:

# [ -w somefile ] && echo rw || echo ro
rw

Que diabos? Claro, o root pode gravar em arquivos somente leitura, mas não deve ter o hábito: as práticas recomendadas tendem a exigir que eu seja capaz de testar o bit de permissão de gravação e, se não for, foi definido dessa maneira por uma razão.

Acho que quero entender por que isso está acontecendo e como posso obter um código de retorno falso ao testar um arquivo que não possui o bit de gravação definido?

Rico
fonte
btw eu estou usando RHEL6 ( 4.1.2(1)-release) e RHEL7 ( 4.2.46(2)-release).
Rich
16
"As melhores práticas tenderiam a exigir que eu fosse capaz de testar o bit de permissão de gravação e, se não for, foi definido dessa maneira por um motivo". - Na verdade, a melhor prática é "não execute coisas como raiz". Se você estiver executando como root, já decidiu ignorar as verificações de permissão. Reimplementar manualmente essas verificações de permissão no espaço do usuário é uma receita para o desastre .
Kevin
@ Kevin Bom para você, se você pode executar coisas sem privilégios. Isso é para manipulação /etc/dhcp/dhcpd.conf, que pertence à raiz. Estou usando o fornecido pelo fornecedor dhcpd. Desastre total, não é? O arquivo é verificado em RCS, estou automatizar uso de rcsdiff, cie coporque temos operadores que precisam ... operar. A verificação de bits de permissão ( -wconforme detalhado por test(1)) seria a primeira linha de falha, trabalhando com base no que ci -udeixa um arquivo somente leitura. Estou abandonando isso e indo direto para rcsdiff -qe verificando $?. Desastroso dhcpd? Seria propriedade de dhcpd.
Rich
1
É um desastre em potencial , porque agora você tem duas implementações diferentes de verificações de permissões: uma no kernel e outra no espaço do usuário. Pior ainda, essas implementações não têm a intenção de produzir resultados idênticos; portanto, você não pode simplesmente testá-las uma contra a outra. Portanto, agora você tem dois caminhos de acesso que devem ser bloqueados e protegidos independentemente um do outro.
Kevin
@ Kevin Claro, eles não produzem resultados idênticos e não foram planejados (apesar da escassez de detalhes nas páginas de manual), mas quero explicitamente verificar o bit de permissão de gravação ; e as páginas do homem bashe testme levaram a acreditar que [ -wé para isso.
Rich

Respostas:

26

test -waka [ -wnão verifica o modo de arquivo. Ele verifica se é gravável. Para raiz, é.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

A maneira como eu testaria seria fazer uma comparação bit a bit com a saída de stat(1)(" %a Direitos de acesso em octal").

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Observe que o subshell $(...)precisa de um 0prefixo para que a saída de statseja interpretada como octal por (( ... )).

Patrick
fonte
Obrigado por ser conciso. Bom uso de (( ... & ... )). Um erro de digitação corrigido :-)
Rich
Torne isso 3 ... Não ifnecessário, a saída de permissões octal %anão é %de (( ... ))precisa de um prefixo 0para interpretar a saída statcomo octal.
Rich
@Patrick my man statdiz "% d número do dispositivo em decimal", mas o que queremos são os "direitos de acesso", não? Seu ponto de vista sobre a necessidade do prefixo 0 é bem-feito, mas acho que só precisamos insistir nele :).
sourcejedi
2
stat -c 0%a...
sourcejedi
@sourcejedi ack, você está certo. Por alguma razão, eu pensava que% d eram direitos de acesso em decimal. Restaurou a edição. obrigado :-)
Patrick
30

Eu acho que você entendeu mal o que -wfaz. Ele não verifica se o arquivo tem "Permissões de gravação", verifica se o arquivo é gravável pelo usuário que está chamando .

Mais especificamente, chama access(2)ou similar.

por exemplo, se um script tiver if [ -w /etc/shadow ], se você executar straceo script, poderá ver uma linha semelhante a

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

Como rootpode gravar no arquivo, ele retorna 0.

por exemplo, como um usuário normal:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

Como raiz

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

Isso, apesar do fato de /etc/shadowter permissão 000na minha máquina.

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

Agora, o que você quer fazer fica interessante e não é tão simples.

Se você quiser verificar as permissões simples, verifique a lssaída ou ligue statou similar. Mas saiba que as ACLs podem substituir essas permissões. Só porque um arquivo tem permissão 400, não impede que ele seja gravável ...

Stephen Harris
fonte
Não, "incompreensão" estaria lendo as páginas de manual incorretamente, pois -w: test(1)é explícito: "FILE existe e a permissão de gravação é concedida", não "o arquivo pode ser gravado pelo usuário atual ". Nada sobre a substituição de permissões, nem ACLs. bash(1)é cauteloso: "Verdadeiro se o arquivo existir e for gravável ." ksh(1)faz uma dica sutil em relação às travessuras: "-w file // True, se o arquivo existir e for gravável pelo processo atual ". zsh(1)adia test(1), zshmisc(1)é redigido como ksh(1)e zshexpn(1)detalha alguns globbing interessantes baseados em permissões. csh(1)é hilariamente breve: "Acesso de gravação".
btw: Aceitei a resposta de Patrick, 1. porque você não respondeu adequadamente à pergunta inicial: como posso obter um código de retorno falso ao testar um arquivo que não possui o bit de gravação definido? e 2. por causa da entrada sarcástica, presumindo que eu entendi mal as páginas de manual.
Rich
3
@ Rich A maneira como eu li isso, acho que seus comentários estão parecendo um pouco sarcásticos também. Não estou dizendo que tudo que você escreveu estava errado, apenas que provavelmente seria melhor se expressado de uma maneira mais educada.
David Z
3
"Eu acho que você entendeu errado ..." não é brincalhão. Sua resposta, no entanto, 100% sarcástica.
churrasco
@ Rich Além disso, embora as páginas de manual possam não ter sido claras, Stephen afirmou que você pode ter "entendido mal o que -w faz ", e não o que dizem as páginas de manual , onde o primeiro parece ser o caso, daí a pergunta
Sebi
1

O usuário root pode fazer o que bem entender, as permissões de arquivo "normais" não são uma limitação. Ele não executará diretamente um arquivo simples sem nenhuma permissão eXecute, apenas para um pouco de segurança contra a prática de tiro ao alvo.

vonbrand
fonte