Hi, here is the test program and the Makefile I used to reproduce this. The test program does not have a fork() anymore (I had one, but it messed up the output and wasn't relevant anyway, so I removed it).
Here is the output on GNU/Linux: marcus@ulysses[0]:/tmp$ make check cc savedid-test.c -o savedid-test cp savedid-test savedid-test-nogid sudo chgrp utmp savedid-test sudo chmod g+s savedid-test ./savedid-test Startup: Real ID 1005, Effective ID 43. Preexec: Real ID 1005, Effective ID 1005. Startup: Real ID 1005, Effective ID 1005. Seteuid: Real ID 1005, Effective ID 1005. Here on GNU/Hurd: marcus@drizzt:~$ make check cc savedid-test.c -o savedid-test cp savedid-test savedid-test-nogid sudo chgrp utmp savedid-test sudo chmod g+s savedid-test ./savedid-test Startup: Real ID 1000, Effective ID 43. Preexec: Real ID 1000, Effective ID 1000. Startup: Real ID 1000, Effective ID 1000. Seteuid: Real ID 1000, Effective ID 43. Thanks, Marcus -- `Rhubarb is no Egyptian god.' Debian http://www.debian.org [EMAIL PROTECTED] Marcus Brinkmann GNU http://www.gnu.org [EMAIL PROTECTED] [EMAIL PROTECTED] http://www.marcus-brinkmann.de
#include <unistd.h> int main (int argc, char *argv[]) { int real_id = getgid (); int eff_id = getegid (); printf ("Startup: Real ID %i, Effective ID %i.\n", getgid (), getegid()); if (argc > 1) { int old_saved_id = atoi (argv[1]); setegid (old_saved_id); printf ("Seteuid: Real ID %i, Effective ID %i.\n", getgid (), getegid()); } else { char *args[] = { 0, 0, 0 }; asprintf (&args[0], "%s-nogid", argv[0]); asprintf (&args[1], "%i", eff_id); setgid (real_id); printf ("Preexec: Real ID %i, Effective ID %i.\n", getgid (), getegid()); execvp (args[0], args); } return 0; }
all: savedid-test cp savedid-test savedid-test-nogid sudo chgrp utmp savedid-test sudo chmod g+s savedid-test check: all ./savedid-test