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

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

Temos imagens Linux baseadas em RH; nos quais tenho que "aplicar" algum "arquivo especial" para atualizá-los para a versão de desenvolvimento mais recente do nosso produto.

A pessoa que criou o arquivo percebeu que em nossa imagem 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 estava em execução, surgiram problemas obscuros.

O que descobri mais tarde: o chamado parachgrpvaiclaroas informações do bit setuid em nossos binários em /whatever.

E o verdadeiro problema é: alguns dos nossos bináriosdevetenha esse bit setuid definido para funcionar corretamente.

Resumindo: existe uma maneira de executar o comando "chgrp"semmatando meus bits setuid?

Acabei de executar 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 -> então, sim, setuid

chgrp -R myuser .
ls -al blub 

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

Responder1

Se você deseja implementar o seu chgrp -R nobody /whateverenquanto retém o bit setuid, você 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 bit setuid definido. O primeiro comando então aplica o chgrpe depois a chmodpara restabelecer o bit setuid que foi eliminado. O segundo se aplica chgrpa todos os arquivos que não possuem um bit setuid.

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

Responder2

Limpar os 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, presumo) significaexecute este programa com o grupo efetivo do proprietário do grupo.

Se você mudar o proprietário do grupo, então em termos de segurança e controle de acesso isso será algo totalmente diferente, ou seja, em vez de rodar com grupo efetivo uvwo programa agora roda com grupo efetivo xyz.

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

Adendo: Na alegação de que chgrp (ou chown) deve apenas limpar SGID (ou SUID, respectivamente)

Ao chowning ou chgrping você altera a configuração de segurança de um executável e isso é 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 este fim, remover SUID e SGID em qualquer mudança de propriedade é simplesmente uma rede de segurança - afinal, na história do Unix/Linux houve algumas vulnerabilidades devido a configurações equivocadas de SUID ou SGID.

Portanto, não há nenhuma razão mais profunda para o Unix se comportar dessa maneira, é apenas uma decisão conservadora de design.

Responder3

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, e não por chgrpsi só. Então a única maneira é restaurá-lo depois.

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 (como root):

chown_preseve_sec :newgroup file1 file2...

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

Recursivamente, você poderia 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=-

(isso tudo presumindo que nada esteja atrapalhando os arquivos ao mesmo tempo).

Responder4

Como de costume na administração, há muitos caminhos a seguir.

A solução que coloquei é 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

informação relacionada