I wrote a simple program as follows -
int main(int argc, char* argv[]) {
setuid(0);
setgid(0);
printf("Current uid and euid are %d, %d\n", getuid(), geteuid());
while(1);
}
I compiled this as root and set the setuid bit using sudo chmod +s test
.
When this program is run as a non-privileged user from bash, the program prints -
Current uid and euid are 0, 0
and then gets stuck in an infinite loop.
However I can still kill this process by pressing Crl+C. If I understand correctly, bash(running as a non-privileged user) should not be able to send SIGINT to a root process.
I also tried the same with kill <pid of test>
and that fails as excepted.
How is bash able to kill the process? Is there a special relationship between the parent process and the child process?
I also tried this other wrapper program -
int main(int argc, char* argv[]) {
pid_t p = fork();
if (p == 0) {
char * args[] = {"./test", NULL};
execv("./test", args);
} else {
sleep(4);
int ret = kill(p, 9);
printf("Kill returned = %d\n", ret);
return 0;
}
}
And ran it as an unprivileged user (where test
has setuid bit set by root). In this case the parent is not able to kill the child. the kill
call returns -1 and the test
process gets orphaned.
What is happening here? What does bash do special that it can kill the children processes it spawns?