Linux aberto () syscall e permissões de pasta

1

Eu tenho um processo P que é gerado por um processo de propriedade do root. Depois que P é criado, setguid () e setuid () são chamados e ele é executado como usuário U .

O processo P tenta criar um arquivo f em uma pasta F (no sistema de arquivos raiz) que é de propriedade de root e tem os seguintes privilégios:

drwxrwx---    2 root     root

A aparência da função parece assim:

open(path , O_CREAT | O_RDWR , 0660);

Se eu executar o comando ps -e -o cmd, uid, uid, ruid, suid, gid, egid, rgid, sgid o resultado é o seguinte:

/my/process    500   500   500   500   500   500   500   500

Isso confirma que o processo P não está sendo executado como root, por estranho que pareça, mesmo que o processo seja executado como usuário U , o arquivo f é crie sob a pasta F , que deve ser gravável apenas pelo usuário root e seus membros:

-rw-rw---- 1 U U

O arquivo é de propriedade de U .

Se eu tentar fazer o mesmo no bash, recebo uma "Permission Denied" como esperado:

$ touch /F/f
touch: cannot touch '/F/f': Permission denied

Se eu definir as permissões da pasta F como:

drwx------    2 root     root

então a chamada open () falha com "Permission Denied" conforme esperado.

Por que o P cria o arquivo nessa pasta quando a permissão de gravação foi concedida ao grupo raiz?

O comando ps mostra que todos os uid e gid estão configurados para os IDs de usuários relacionados. Então, como isso é possível?

Estes são os membros do grupo de raiz e U :

$groups root
root : root

$groups U
U : U G

Então U tem G como grupo secundário

$lid -g root
 root(uid=0)
 sync(uid=5)
 shutdown(uid=6)
 halt(uid=7)
 operator(uid=11)

$lid -g U
 U(uid=500)

$lid -g G
 U(uid=500)

Este programa mostra que apenas U é membro de G

    
por Bemipefe 15.11.2017 / 20:54

1 resposta

1

Como @jdwolf menciona nos comentários, a questão pode ser grupos suplementares. setgid() não os remove.

Um teste simples, ./drop aqui é um programa que chama setregid() e setreuid() para alterar o GID e o UID para nobody e, em seguida, executa id :

# id
uid=0(root) gid=0(root) groups=0(root)
# ./drop
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup),0(root)

Ainda há o grupo zero. Adicionar setgroups(0, NULL) (antes do setuid() ) remove esse grupo:

# ./drop2
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

Claro, isso não adiciona nenhum dos outros grupos de usuários alvo.

    
por 16.11.2017 / 10:33