2016-08-23 62 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之前,您將放棄權限並打印錯誤消息。