É porque você é muito cedo, se você esperar até que os UIDs sejam alterados, seu processo será executado como user2
. Isso funcionou para mim:
./program "test" &
PID=$!
sleep 0.0005
kill -SIGSTOP $PID
grep ^Uid /proc/$PID/status
Outra tentativa é adicionar um atraso com usleep()
e enviar o SIGSTOP
mais tarde durante esse período. Então o programa é executado com user2
como uid efetivo. Você pode verificar isso, mas sem anexar com gdb
ou strace
. Muito provavelmente é algum tipo de linux kernel interna, que o processo precisa de algum tempo para mudar os UIDs.
Ao executar o processo a partir de um terminal, o execve()
syscall é chamado; da manpage:
If the set-user-ID bit is set on the program file pointed to by filename, [...] and the calling process is not being ptraced, then the effective user ID of the calling process is changed to that of the owner of the program file.
Quando você anexar gdb
ao processo, não verá o fluxo de user2
, porque você está ptrace
do processo, conforme descrito na página de manual acima. Ou então você poderia anexar a um sudo
-process e obter permissões de root.
No entanto, esse programa nunca recebe uma falha de segmentação ( SIGSEGV
), a menos que você force um com kill -SIGSEGV $PID
. SE seu programm recebe uma SIGSEGV
, a rotina launch_debugger()
é chamada. Isso chamará um gdb
e como argumento apenas o seu program
binário sem nenhum argumento, o que substituirá o processo atual em execução. Portanto, no depurador teremos privilégios de user2
e, portanto, você pode fazer o que quiser lá, com as permissões de user2
.
Você pode, por exemplo, fazer o seguinte dentro de gdb
:
(gdb) file bash
Reading symbols from /bin/bash...(no debugging symbols found)...done.
(gdb) run
Starting program: /bin/bash
user2@host:~$ id
uid=1035(user2) gid=1003(user1) groups=1035(user2),1003(user1)
Agora, considere o mesmo binário com um bit setuid e o proprietário é root.