Eu li na página de manual a função system
e me deparei com a seguinte passagem que oferece uma explicação:
Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use the exec(3) family of functions instead, but not execlp(3) or execvp(3). system() will not, in fact, work properly from programs with set-user-ID or set- group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup. (Debian uses a modified bash which does not do this when invoked as sh.)
Aqui estão algumas outras postagens do StackExchange que eu li no meu caminho para essa passagem:
- Permissão SETUID negada
- Depurando um programa setuid / “Permission denied” with setuid
- Problema de bit suix do Unix
- como definir o bit setuid em um programa de um usuário não root?
- o linux setuid não funciona
Para a posteridade, e como o exemplo dado pode ser útil para diagnosticar isso ou problemas semelhantes em outros contextos, mantive meu original abaixo.
É possível que você esteja com um bug? Não consegui reproduzir o seu problema em um contêiner do Docker executando o Debian 9 com o gcc 6.3. Aqui está como eu tentei recriar o cenário descrito em sua postagem.
Primeiro, crie os usuários "alice" e "bob" e eles para o grupo "staff":
useradd -m -G staff alice
useradd -m -G staff bob
Em seguida, crie o arquivo e defina sua propriedade e permissões:
# Create a subdirectory to hold the text file
sudo -u alice mkdir -p /home/alice/share/
# Create the text file
sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'
# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt
Vamos verificar os resultados:
$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov 4 15:33 /home/alice/share/foo.txt
Agora vamos criar uma versão do display-foo
que usa a função system
:
$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char **argv) {
struct passwd *r_pwd = getpwuid(getuid());
printf("Real user: %s\n", r_pwd->pw_name);
struct passwd *e_pwd = getpwuid(geteuid());
printf("Effective user: %s\n", e_pwd->pw_name);
system("/bin/cat /home/alice/share/foo.txt");
}
HEREDOC
$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo
E vamos definir propriedade e permissões em display-foo
, incluindo a configuração do bit setuid:
chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo
Vamos também verificar o resultado:
$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov 4 15:40 /usr/local/bin/display-foo
Agora, executamos o programa como alice
e como bob
:
$ sudo -u alice display-foo
Real user: alice
Effective user: alice
This is foo.txt
$ sudo -u bob display-foo
Real user: bob
Effective user: alice
This is foo.txt
Como você pode ver, parece que tudo está funcionando conforme o esperado.