bash 如何使用 CTRL+C 杀死 children 进程

How is bash able to kill children processes with CTRL+C

我写了一个简单的程序如下-

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 的 non-privileged 用户时,程序打印 -

Current uid and euid are 0, 0

然后陷入无限循环。

但是我仍然可以通过按 Crl+C 来终止这个进程。如果我理解正确,bash(运行宁作为 non-privileged 用户)不应该能够将 SIGINT 发送到根进程。

我也对 kill <pid of test> 进行了同样的尝试,但失败了。

bash 如何终止进程? parent进程和child进程有什么特殊关系吗?

我也试过这个其他包装程序 -

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 具有由 root 设置的 setuid 位)。在这种情况下,parent 不能 杀死 child。 kill 调用 returns -1 并且 test 进程被孤立。

这里发生了什么? bash 有什么特别之处可以杀死它产生的 children 进程?

Bash 不需要任何权限,因为 bash 没有做任何事情。当您点击 ^C 时,tty 驱动程序会将 SIGINT 发送到前台进程组中的所有进程。信号来自系统,而不是来自另一个进程,因此与一个进程向另一个进程发送信号相关的权限检查不适用。