我正在编写一个程序,用户可以在/使用sshfs调用mount目录。这是基本布局,省略了错误处理和样板:
uid_t euid, ruid;
void mountDir(char *dirname, char *hostname){
childPid = fork();
if(childPid == 0){
char *sshfsArgs[6] = {"/usr/bin/sshfs", hostName, /*Other args*/};
seteuid(euid);
execv(sshfsArgs[0], sshfsArgs);
//I want to drop my setuid permissions with seteuid(ruid),
//but execv doesn't return.
}else{ //I'm the parent process.
//I don't want to have root permissions now.
wait(childPid);
}
}
void main(int argc, char **argv){
ruid = getuid();
euid = geteuid();
seteuid(ruid); //Drop the root permissions.
char **hostList = {"bulb.example.com", "char.example.com", argv[1]};
char * hostName = pickHost(hostList); //Pings them and picks one that responds.
mountDir("/net/home", hostName);
mountDir("/net/projects", hostName);
}
再次,省略了大量的错误检查。我想在运行sshfs
时才拥有root权限。在调用seteuid
之前有几个放弃fork()
权限的示例,但是在这里我只想在子进程中获取它们,并在execv
之后立即丢失它们。我该如何安全地做到这一点?当子进程执行seteuid
root时会发生什么?父进程是否获得root权限?
答案 0 :(得分:2)
现在处理此问题的方法是正确的。
该过程的第一件事就是删除root权限,因此在那时它是安全的。
在fork
之后,父母等待孩子,孩子会跑seteuid(euid);
。因此,子节点现在以root权限运行(因为这是seteuid
运行的地方)但父节点不是。然后,孩子调用execv
以root权限运行sshfs
。
子节点中的seteuid
调用不会影响父节点,因为它们是单独的进程(即使它们在execv
之前运行相同的代码)。
由于execv
未返回,因此无需再次删除权限。当sshfs
完成时,该过程结束。如果execv
失败,那么您会在调用_exit
之前删除权限并打印错误消息。