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

时间:2016-08-23 03:44:59

标签: c linux exec setuid

我正在编写一个程序,用户可以在/使用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权限?

1 个答案:

答案 0 :(得分:2)

现在处理此问题的方法是正确的。

该过程的第一件事就是删除root权限,因此在那时它是安全的。

fork之后,父母等待孩子,孩子会跑seteuid(euid);。因此,子节点现在以root权限运行(因为这是seteuid运行的地方)但父节点不是。然后,孩子调用execv以root权限运行sshfs

子节点中的seteuid调用不会影响父节点,因为它们是单独的进程(即使它们在execv之前运行相同的代码)。

由于execv未返回,因此无需再次删除权限。当sshfs完成时,该过程结束。如果execv失败,那么您会在调用_exit之前删除权限并打印错误消息。