设置用户ID程序
本文将以两个简单的小程序为例,说明如果在一个设置用户ID程序中调用system将会发生什么:
代码1
#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函数!