子进程需要seteuid为root,父进程不需要

Child process needs to seteuid to root, parent does not

我正在编写一个程序,用户可以调用该程序以使用 sshfs 在 / 中挂载目录。这是基本布局,省略了错误处理和样板文件:

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 权限。有几个在调用 fork() 之前删除 seteuid 特权的例子,但在这里我只想在子进程中获得它们,并在 execv 之后立即失去它们。我如何安全地执行此操作?当子进程对 root 执行 seteuid 时会发生什么?父进程是否获得过root权限?

您现在的处理方式是正确的。

该进程做的第一件事是删除 root 权限,因此此时它是安全的。

fork 之后,parent 等待 child 和 child 运行 的 seteuid(euid);。所以 child 现在是 运行 root 特权(因为那是 seteuid 是 运行 的地方)但 parent 不是。 child 然后以 root 权限调用 execv 到 运行 sshfs

child 中的 seteuid 调用不会影响 parent,因为它们是独立的进程(即使它们 运行 在execv).

既然execv没有return,就没必要再降权了。当 sshfs 完成时,该过程结束。如果 execv 失败,那么您将在调用 _exit.

之前放弃权限并打印错误消息