浅析为什么设置用户ID程序中不能直接调用system函数?

设置用户ID程序

本文将以两个简单的小程序为例,说明如果在一个设置用户ID程序中调用system将会发生什么:


代码1

代码块语法遵循标准markdown代码,例如:

#include "apue.h"
int
main(int argc,char *argv[])
{
int status;

if(argc < 2)
{
err_quit("commondline argument requied");
}
if((status=system(argv[1]))<0)
{
err_sys("err system");
}
pr_exit(status);
exit(0);
}

使用GCC编译成tsys.o可执行文件。


代码2

#include "apue.h"
int
main(void)
{
printf("real uid = %d,effective uid = %d\n",getuid(),geteuid());
exit(0);
}

将代码2编译成idtest.o。


实验过程:

parallels@ubuntu:~/vimtest/apue$ ./tsys.o ./idtest.o
real uid = 1000,effective uid = 1000
normal termination, exit status = 0

修改tsys.o的权限

sudo chown root tsys.o
sudo chmod u+s tsys.o
parallels@ubuntu:~/vimtest/apue$ ./tsys.o ./idtest.o
real uid = 1000,effective uid = 0
normal termination, exit status = 0

虽然已经切换为普通用户,但是tsys.o的有效ID竟然是root。这是一个很大的安全漏洞!原因是,我们在赋予tsys程序的超级用户权限在system中执行了fork和exec后仍被保留下来了。

结论

如果一个进程正以特殊权限设置用户ID或者用户组ID,它又想生成另一个进程执行另一个程序,则它应当直接使用fork和exec。而且在fork和exec之前要改回普通权限。总之,在设置用户ID或者设置组ID的程序中,坚决不应该调用system函数!

相关文章

相关标签/搜索