在vfork()/ clone()中调用execv()之前的setuid()

时间:2012-07-24 10:28:02

标签: c linux

我需要从服务器派生一个exec。由于我的服务器内存占用量很大,我打算使用vfork() / linux clone()。我还需要为stdin / stdout / stderr打开管道。这是clone() / vfork()允许的吗?

2 个答案:

答案 0 :(得分:2)

来自标准:

  

[..]如果由vfork()创建的进程修改除用于存储来自pid_t的返回值的类型vfork()的变量之外的任何数据,则行为未定义,或者从调用vfork()的函数返回,或在成功调用_exit()或其中一个exec函数系列之前调用任何其他函数。

调用setuidpipe等函数的问题在于它们可能影响父进程和子进程之间共享的地址空间中的内存。如果你需要在exec之前做任何事情,最好的方法是编写一个小的填充程序来完成你需要的任何事情然后exec到最终的子进程(也许通过{{提供的参数) 1}})。

argv

答案 1 :(得分:1)

我使用clone()代替,使用CLONE_VFORK|CLONE_VM标志;有关详细信息,请参阅man 2 clone

由于未设置CLONE_FILES,子进程有自己的文件描述符,可以关闭和打开标准描述符,而不会影响父进程。

由于克隆过程是一个单独的过程,因此它有自己的用户和组ID,因此请通过setresgid()setresuid()设置它们(可能会调用setgroups()initgroups()首先设置其他群组(请参阅man 2 setresuidman 2 setgroupsman 3 initgroups了解详情)不会影响家长。

CLONE_VFORK|CLONE_VM标志意味着此clone()应该像vfork()一样,子进程与父进程在同一内存空间中运行直到execve()调用。

这种方法避免了使用中间可执行文件时的延迟 - 这非常重要 - 但这种方法完全取决于Linux。