我写了一个简单的程序如下-
int main(int argc, char* argv[]) {
setuid(0);
setgid(0);
printf("Current uid and euid are %d, %dn", 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 = %dn", ret);
return 0;
}
}
并以无特权用户的身份运行它(其中test
具有由root设置的setuid位(。在这种情况下,父级不能杀死子级。则CCD_ 4调用返回-1并且CCD_。
这里发生了什么?bash有什么特别之处,它可以杀死它产生的子进程?
Bash不需要任何权限,因为Bash什么都不做。当您点击^C时,tty驱动程序会将SIGINT发送到前台进程组中的所有进程。信号来自系统,而不是来自另一个进程,因此与一个进程向另一个发送信号相关的权限检查不适用。