2016-08-23 37 views
1

我正在写一个程序,用户可以调用来挂载/使用sshfs中的目录。这里是基本的布局,错误处理和样板省略:子进程需要seteuid根,父母不

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之后立即失去它们。我如何安全地做到这一点?当一个子进程执行seteuid到根目录时会发生什么?父进程是否获得root权限?

回答

2

你现在处理这种方式是正确的。

该进程所做的第一件事是删除root权限,因此在这一点上是安全的。

fork之后,父母等待孩子,孩子运行seteuid(euid);。所以这个孩子现在以root权限运行(因为这是seteuid运行的地方),但父母不是。然后,该小孩拨打execv以root权限运行sshfs

seteuid调用子代不会影响父代,因为它们是单独的进程(即使它们在execv之前运行相同的代码)。因为execv不返回,所以不需要再次删除权限。当sshfs完成时,该过程结束。如果execv失败,则在调用_exit之前,您将放弃权限并打印错误消息。