Por que privs são obrigados a setgid () para grupos suplementares

8

As várias set*gid()chamadas do sistema exigem privilégios para alterar grupos, exceto em poucos casos. Alterar o grupo primário para um dos grupos suplementares dos processos não parece ser um deles, o que significa que os comandos newgrp/, sgpor exemplo, precisam elevar privilégios para alternar o grupo primário.

Existe uma razão para setgid()/ setegid()/ setregid()/ setfsgid()não permitir a mudança para um grupo suplementar sem privs? Em caso afirmativo, qual o motivo?

William Hay
fonte
1
Não tenho certeza também. Observe que você pode chgrp um arquivo para um de seus grupos suplementares; portanto, se você tiver acesso de gravação a uma área sem noexec, nosuid, poderá solucionar essa limitação (criando uma cópia /usr/bin/envcom a permissão setgid).
Stéphane Chazelas 23/02
O comando newgrp já faz isso comigo, mas gerar um programa externo nem sempre é o que se deseja fazer.
William Hay
Observe que newgrp/sgse refere ao banco de dados da conta, não à lista de grupos suplementares do processo.
Stéphane Chazelas 23/02
Se o seu gid também não estiver na sua lista de IDs suplementares, permitir setgid()lhe permitirá deixar a associação de um grupo (o que seria uma preocupação de segurança), mas, novamente, você também poderá fazê-lo com o mesmo truque executável do setgid como acima, e seu gid geralmente também está na sua lista suplementar ( initgroups(3)usa um argumento gid apenas para isso).
Stéphane Chazelas 23/02

Respostas:

3

Obviamente, o enigma fundamental aqui é que as verificações de permissão do sistema de arquivos se baseiam na combinação (do UID efetivo e) do GID efetivo e dos GIDs complementares. Portanto, do ponto de vista das verificações de permissões de arquivo, o GID efetivo é equivalente aos GIDs suplementares, o que leva à pergunta do OP. (De passagem: se estamos falando sobre Linux, na verdade são os UID / GID do sistema de arquivos usados ​​nas verificações de permissão do sistema de arquivos, em vez dos UID e GID efetivos, mas os IDs anteriores quase sempre têm os mesmos valores que os IDs anteriores. )

Portanto, deve haver alguns casos em que os GIDs reais / efetivos / salvos não são equivalentes aos GIDs suplementares. (Agrupo os GIDs reais / efetivos / conjunto salvo, porque as regras normais de permissão set * gid () dizem que um processo sem privilégios pode alterar qualquer um desses GIDs para o mesmo valor que um dos outros dois.

E, de fato, existem alguns desses casos. O access (2) faz suas verificações com base no ID do usuário real e no ID do grupo. Se um usuário sem privilégio conseguir alterar o ID do grupo real para ser o mesmo de um dos GIDs suplementares que não são o GID definido ou salvo ou salvo, o comportamento do acesso (2) poderá ser manipulado.

Existem outros casos desse tipo. Veja a página do manual Linux mkdir (2) , para um exemplo. Dependendo se o bit do modo set-GID está definido no diretório pai, um novo arquivo criado no diretório obtém sua propriedade de grupo do GID efetivo do processo de criação. Novamente, se um processo sem privilégios puder mudar seu GID efetivo para ser o mesmo que um de seus GIDs complementares, ele poderá manipular a propriedade do grupo de novos arquivos de maneiras inesperadas. Comentários semelhantes se aplicam ao mknod (2) e o IPC do System V chama semget (2), shmget (2) e msgget (2).

Há também alguns casos específicos do Linux em que os GIDs reais / efetivos / salvos não são equivalentes aos GIDs suplementares. Veja process_vm_readv (2) e prlimit (2), por exemplo.

mtk
fonte
Nota: @mtk é o autor de The Linux Programming Interface .
Stéphane Chazelas
O gid efetivo determina a propriedade do grupo de novos arquivos. Mas então você pode alterar esse grupo para um dos seus gids suplementares posteriormente (e também fornecer o bit setgid, permitindo que seu processo efetivamente execute um setgid ()). Parece um pouco um motivo fraco.
Stéphane Chazelas
@ StéphaneChazelas: concordou, é um pouco fraco. Na OTOH, agora é um processo de duas etapas, que (e estou chegando aqui) tem potencial para raças estranhas. Mas, além desse caso, existem os outros que mencionei acima. Não sei qual o motivo exato da decisão de design. Talvez tenha sido o acesso (2), já que essa é uma parte antiga da API. Muitos dos outros só chegaram mais tarde (ou são específicos do Linux) ou (eu presumo) não estavam presentes no BSD quando GIDs adicionais foram adicionados. Ou, talvez, tratasse apenas de preservar o comportamento histórico; Vejo que você adicionou esse ponto como resposta.
mtk
3

Eu acho que o motivo é principalmente histórico. Grupos suplementares não foram adicionados até 4.2BSD (por volta de 1983). Antes disso, você tinha apenas os recursos reais e eficazes.

O comportamento de setuid / setgid era completamente simétrico e não tinha motivos para não ser. Você trocaria usuário sue agruparia com sg/ newgrptodos os executáveis ​​setuid. As informações sobre a associação ao grupo de usuários residiam apenas no banco de dados do usuário, não nos atributos dos processos.

E a interface setuid / setgid não foi alterada quando gids suplementares foram adicionados.

Tecnicamente agora, se você tiver acesso de gravação a um sistema de arquivos (em que a execução e setuid / setgid não estão desabilitadas), ainda poderá definir seu ID de usuário efetivo ou real para qualquer um dos seus gids complementares (sem ter que recorrer a sg/ newgrpqual btw somente permite mudar para grupos definidos no banco de dados do usuário, que não é necessariamente o mesmo que a lista de gids complementares do processo).

cp /usr/bin/env .
chgrp any-sup-group env
chmod g+s ./env

E após a execução env, o seu egid muda para any-sup-group.

Stéphane Chazelas
fonte