Associações de grupos e processos setuid / setgid

9

Os processos que desalavancam os privilégios através de setuid() e setgid() parecem não herdar os membros do grupo do uid / gid que eles configuram.

Eu tenho um processo de servidor que deve ser executado como root para abrir uma porta privilegiada; depois disso, ele desacelera para um uid / gid específico não privilegiado, 1 , por exemplo, o usuário foo (UID 73). O usuário foo é um membro do grupo bar :

> cat /etc/group | grep bar
bar:x:54:foo

Portanto, se eu fizer login como foo , posso ler um arquivo /test.txt com estas características:

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

No entanto, o seguinte programa C (compilar std=gnu99 ), quando executar root:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

Sempre informa Permissão negada . Eu imagino que isso tenha a ver com o fato de ser um processo que não é de login, mas é uma espécie de isquiotibiais do modo como as permissões devem funcionar.

1. Que é frequentemente SOP para servidores, e eu acho que deve haver uma maneira de contornar isso como eu encontrei um relatório

    
por goldilocks 08.03.2014 / 23:06

2 respostas

13

O problema é que setuid e setgid não são suficientes para fornecer ao seu processo todas as credenciais necessárias. As autorizações de um processo dependem de

  • seu UID
  • seu GID
  • seus grupos suplementares
  • suas capacidades.

Veja man 7 credentials para obter uma visão geral mais detalhada. Portanto, no seu caso, o problema é que você configura corretamente o UID e o GID, mas não define os grupos suplementares do processo. E o grupo bar tem GID 54, não 73, por isso não é reconhecido como um grupo em que seu processo está.

Você deve fazer

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  
    
por 08.03.2014 / 23:52
0

OK, vasculhei a rede um pouco. Eu pensei no princípio que APUE teria todas as respostas, mas estava enganado. E minha cópia (edição antiga) está funcionando, então ... O Manual de Administração do Unix e Linux do capítulo 5 parece promissor, mas eu não entendi (apenas uma cópia das duas primeiras edições, também no trabalho).

Os pequenos recursos que eu encontrei (google para "daemon writing unix") falam sobre passos importantes, como dissociar o tty, etc. Mas nada sobre o UID / GID. Estranhamente, nem mesmo a extensa coleção HOWTO no link parece ter detalhes. Apenas excitação é de Jason Short Vamos escrever um Linux Daemon - parte I . Detalhes completos sobre como o SUID / SGID e toda essa bagunça funciona são os SUID desmistificados de Chen, Wagner e Dean (um artigo na USENIX 2002). Mas tenha cuidado, o Linux tem um UID extra, o FSUID (veja Notas de Incompatibilidade Unix do Wolter: Funções de configuração do UID para uma discussão).

Daemonizing um processo definitivamente não é para os fracos de coração. As considerações gerais de segurança são fornecidas em Programação Segura para Linux e Unix HOWTO - Criando Software Seguro de D. Wheeler. O Systemd promete simplificar a maior parte (e, assim, reduzir o espaço para erros que levam a problemas de segurança), veja o manual do daemon .

    
por 09.03.2014 / 01:58