【发布时间】:2021-02-23 02:50:45
【问题描述】:
我写了一个简单的程序如下-
int main(int argc, char* argv[]) {
setuid(0);
setgid(0);
printf("Current uid and euid are %d, %d\n", getuid(), geteuid());
while(1);
}
我将它编译为 root 并使用 sudo chmod +s test 设置 setuid 位。
当这个程序作为非特权用户从 bash 运行时,程序会打印 -
当前 uid 和 euid 为 0, 0
然后陷入无限循环。
但是我仍然可以通过按 Crl+C 来终止此进程。如果我理解正确,bash(以非特权用户身份运行)应该无法将 SIGINT 发送到根进程。
我也对kill <pid of test> 进行了同样的尝试,但由于例外而失败。
bash 是如何杀死进程的?父进程和子进程之间是否有特殊关系?
我也试过这个其他的包装程序 -
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;
}
}
并以非特权用户身份运行它(test 的 setuid 位由 root 设置)。在这种情况下,父母无法杀死孩子。 kill 调用返回 -1,test 进程被孤立。
这里发生了什么? bash 有什么特别之处可以杀死它产生的子进程?
【问题讨论】: