Como evitar que o chgrp limpe o “bit setuid”?


8

Temos imagens Linux baseadas em RH; no qual tenho que "aplicar" alguns "arquivos especiais" para atualizá-los para a versão de desenvolvimento mais recente do nosso produto.

A pessoa que criou o arquivo concluiu que dentro da nossa imagem de base, algumas permissões estão erradas; então nos disseram para correr

sudo chgrp -R nobody /whatever

Nós fizemos isso; e mais tarde, quando nosso aplicativo está sendo executado, surgiram problemas obscuros.

O que eu achei mais tarde: a chamada para chgrp irá limpar as informações bit setuid em nossos binários dentro / whatever.

E o problema real é: alguns de nossos binários devem ter esse bit setuid definido para funcionar corretamente.

Para encurtar a história: existe uma maneira de executar esse comando "chgrp" sem matar meus bits setuid?

Eu apenas executei o seguinte no meu Ubuntu local; levando ao mesmo resultado:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

-> mostra o nome do arquivo com fundo vermelho -> sim, sim, setuid

chgrp -R myuser .
ls -al blub 

-> mostra o nome do arquivo sem fundo vermelho -> setuid desapareceu


1
O 4XXXbit é chamado bit setuid ( s), não pegajoso. Pegajosa é o tbit e seu objetivo é um pouco diferente: en.wikipedia.org/wiki/Sticky_bit
— Zuazo

2
(1) Você está definindo o setuidbit, não o stickybit. (2) Não limpar o setuidbit quando você faz chgrpou chownseria um problema de segurança.
— Satō Katsura

1
Esse comportamento muda entre distribuições. Mas, como explicado aqui , a alteração do bit setuid depende do comportamento subjacente do syscall.
— Zuazo 30/09/16

Obrigado a todos. Você está correto, isso é sobre o bit setuid! Obrigado pela ajuda. E eu também aceito que isso é "funciona como projetado". Agora eu só preciso encontrar a maneira mais sensata de fazer o que precisa ser feito sem matar esses bits. Considero usar o gefacl para criar um despejo de texto, refazer a configuração do texto e aplicar esse. Isso deve me dar controle total sobre o que vai acontecer.
— GhostCat 30/09/16

Respostas:


7

Se você deseja implementar seu chgrp -R nobody /whateverenquanto retém o bit setuid, pode usar estes dois findcomandos

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

A find ... -perm 04000opção seleciona arquivos com o conjunto de bits setuid. O primeiro comando aplica oe, em chgrpseguida, a chmodpara restabelecer o bit setuid que foi eliminado. O segundo se aplica chgrpa todos os arquivos que não possuem um bit setuid.

De qualquer forma, você não deseja chamar chgrpou chmodusar links simbólicos, pois isso afetaria seus destinos, daí o ! -type l.


Observe que chgrptambém limpa o bit setgid (e os recursos no Linux) que também podem precisar ser restaurados.
— Stéphane Chazelas

@ StéphaneChazelas você está certo, mas como ninguém mencionou o setgid, não me preocupei em fornecer uma solução para isso. A solução é trivialmente extensível, embora, com um terceirofind
— roaima

Bem, não pode ser uma terceira descoberta, você teria que cobrir os casos u + g, u sozinho, g sozinho. De qualquer forma, você deve conseguir fazer isso em uma findchamada. Eu não gosto das longas linhas no SE quando você precisa rolar o texto. Minha adição do! tipo eu fiz isso ultrapassar os limites
— Stéphane Chazelas 30/09

Bem, pode ser difícil fazer uma findabordagem -exec +confiável se isso acabar dividindo o chmod/ chgrps em várias invocações.
— Stéphane Chazelas

1
Na verdade, acho que find . ! -type l -exec chgrp nobody {} + \( -perms -6000 -exec chmod gu+s {} + -o -perms -4000 -exec chmod u+s {} + -o -perms -2000 -exec chmod g+s {} + \)deve ficar bem. Como as chgrpcorrespondências para mais arquivos, para cada arquivo, devem ser feitas antes dos chmod.
— Stéphane Chazelas

5

A limpeza de bits SUID e SGID em chgrp(ou chown) é perfeitamente razoável. É uma medida de segurança para evitar problemas de segurança. Para SGID (em executáveis, eu presumo) significa executar este programa com um grupo efetivo do proprietário do grupo .

Se você alterar o proprietário do grupo, em termos de segurança e controle de acesso, isso é algo completamente diferente, ou seja, em vez de executar com o grupo efetivo, uvwo programa agora será executado com o grupo efetivo xyz.

Portanto, você deve restaurar o bit SUID ou SGID explicitamente na mudança de propriedade.

Adendo: sob a alegação de que chgrp (ou chown) deve apenas limpar o SGID (ou SUID, resp.)

Ao chowning ou chgrping, você altera a configuração de segurança de um executável, e esse é um motivo suficiente para limpar quaisquer atributos de elevação de privilégio. O poder do Unix vem da simplicidade conceitual, e a segurança do Unix já é bastante complicada. Para esse fim, remover o SUID e o SGID em qualquer mudança de propriedade é simplesmente uma rede de segurança - afinal, na história do Unix / Linux, havia algumas vulnerabilidades devido a configurações equivocadas de SUID ou SGID.

Portanto, não há uma razão mais profunda pela qual o Unix se comporte dessa maneira, é apenas uma decisão de design conservadora.


1
Isso explica perfeitamente porque a mudança de proprietário limpa o bit SUID e a mudança de grupo limpa o bit SGID. Mas a pergunta é sobre o bit SUID durante uma operação de alteração de grupo que não afeta o usuário sob o qual o SUID é executado. Portanto, tem que haver uma explicação diferente.
— Ben Voigt

1
@ BenVoigt: explica muito bem. Tanto o chown quanto o chgrp chamam o syscall chown (), que limpa suid e sgid em arquivos regulares, não importa o quê.
— Joshua

1
@ Josué: Essa é uma descrição. A explicação é "para evitar o caso de que, em vez de executar com grupo efetivo, uvwo programa agora seja executado com grupo efetivo xyz", mas isso não se aplica ao caso em discussão.
— Ben Voigt

Faz. Ao alterar chownou chgrpalterar a configuração de segurança, esse é um motivo suficiente para limpar os atributos de elevação de privilégio. Há grandes chances de que isso atinja os incautos.
— countermode

4

A limpeza do bit setuid, setgid(pelo menos no Linux) em não-diretórios é feita pelo kernel na chown()chamada do sistema feita por chgrp, não por chgrpsi só. Portanto, a única maneira é restaurá-lo posteriormente.

Ele também limpa os recursos de segurança.

Então, no GNU Linux:

chown_preserve_sec() (
  newowner=${1?}; shift
  for file do
    perms=$(stat -Lc %a -- "$file") || continue
    cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
    chown -- "$newowner" "$file" || continue
    [ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
    chmod -- "$perms" "$file"
  done
)

E execute (as root):

chown_preseve_sec :newgroup file1 file2...

para alterar o grupo enquanto tenta preservar as permissões.

Recursivamente, você pode fazer:

# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)

chgrp -RP nobody .

# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z  "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-

(tudo isso assumindo que nada está atrapalhando os arquivos ao mesmo tempo).


1

Como de costume na administração, existem muitos caminhos a percorrer.

A solução que eu coloquei foi assim:

cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null

# A) change lines starting with      # group: root
# to                                 # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new

# B) change lines with               group::x.y
# to                                 group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.