精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>未整理到对应目录的文章>>为什么不能用system()?--大部分是抄的,写错的地方多多提意见

主题:为什么不能用system()?--大部分是抄的,写错的地方多多提意见
发信人: smokefire(怒放,怒放)
整理人: yangcs(2004-10-14 14:22:35), 站内信件
Unix环境高级编程笔记(二)

为什么不用system()
unix环境高级编程里面有这么一句话,设置-用户-id或设置-用户组-id程序,决不应调用system()函数。但是原因说得不是很具体,以前我写suid和guid程序的时候,通常都是调用system函数而不是用exec因为system比较简单,而exec太麻烦了。一个经典的exec程序如下代码:

pid_t pid;
//建立一个新进程
if((pid=fork())<0)//如果建立失败
{
//这儿写异常处理
}
else if(pid==0)//子进程
{
execl(“/bin/sh”,”sh”,”-c”,”MYPROGRAM”,(char *)0);//调用我需要执行的程序
_exit(127)//如果调用失败
}
else
{
if(waitpid(pid,NULL,0)<0) //父进程调用wait阻塞
//wait失败的异常处理
}

如果用system,就可以直接
system(“MYRPOGRAM”);
很方便,但是等等!为什么那么多程序都不调用system而要麻烦的调用exec呢?system会有权限问题,让我们做个测试:
//runroot.c
int main(int argc,char *argv[])
{
system(argv[1]);//代码执行程序的跟着的参数 未对参数合法性进行检查 J
exit(0);
}
用root用户编译 并给予文件suid和guid属性
#gcc runroot.c –o runroot
#chmod g+s runroot
//test.c
int main(void)
{
printf(“real uid is %d and effective uid is %d\n”);//打印实际用户ID和有效用户ID的值.
}
//这段代码和上断代码从书上抄的
用普通用户编译
$gcc test.c –o test
OK,我们现在用informix用户运行runroot test
$real uid is 102 and effective uid is 0
有效用户变成了root!这就意味这如果我取得了informix用户的权限 如果修改test程序的内容,那我就能够取得系统管理的权限!比如我让程序修改/etc/passwd。
所以,不能在suid和guid程序中使用system,而应该使用exec,而且!在使用exec函数之前,应该调用setuid()将有效用户ID和实际用户ID改成需要的。在某个用户被黑之后,不至于造成太大的损失。值得一提的是,我现在用的SunOS5.7系统,system函数不存在这个问题,当你调用system的时候,有效用户ID是你文件的所有者。但是linux和ture unix64却不是这样。关于这些有些争论,但是基本的论调是应该把权利交给程序员的自觉性,毕竟大家都喜欢没太多限制的东西。
综合我以前犯的一些错误,如果你要设置suid和guid位,你要非常小心,起码常识是你不能让suid和guid程序是普通用户可写的,(如果可写,那就失去了一切)第二 不要调用system. 第三 fork()之后调用exec函数之前先收回权限。还有如果你要让你exec的程序去干有特权的活,你就让那个程序是root所有,其他任何用户都是不可写的。






[关闭][返回]