在守护进程中这样的代码中:
// run as root, after initgroups(...), setgid(...)
setuid(user);
const char* args[] = {"./userbinary",0};
execv("userbinary", args);
_exit(1);
有一个明显的问题,用户可以在调用setuid
和exec[lvpe]
之间附加到进程,并读出所有进程的内存,包括敏感变量和状态。
我使用的解决方法是这样的(显然,省略了所有错误处理):
// run as root in daemon
const char* args = {"/usr/bin/mysetuid", uidStr, "./userbinary", 0};
execv("/usr/bin/mysetuid", args);
_exit(1);
// mysetuid.c:
int main(int arc, char* argv[]) {
setuid(atoi(argv[1]));
execv(argv[2], argv+2);
exit(1);
}
执行此操作的“标准”方式是什么?使用辅助二进制文件似乎最安全,但我找不到其他应用程序执行此操作。例如,OpenSSH只依赖于每个用户的连接都有自己的进程这一事实,因此setuid
总是来自一个几乎空白的进程。