2016-08-23 5 views
1

입니다. 사용자가 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을 실행할 때만 루트 권한을 갖고 싶습니다. fork()을 호출하기 전에 seteuid 권한을 삭제하는 몇 가지 예가 있지만 여기서는 자식 프로세스에서만 이러한 권한을 얻고 싶습니다. execv 후에 바로 그 권한을 잃고 싶습니다. 어떻게하면 안전하게 처리 할 수 ​​있습니까? 자식 프로세스가 루트로 seteuid을 수행하면 어떻게됩니까? 상위 프로세스가 루트 권한을 얻습니까?

답변

2

지금 처리하는 방식이 정확합니다.

프로세스가하는 첫 번째 일은 루트 권한을 삭제하는 것이므로 그 시점에서 안전합니다.

fork 뒤에 부모는 자식을 기다리고 자식은 seteuid(euid);으로 실행됩니다. 따라서 자식은 루트 권한으로 실행 중입니다. (즉, seteuid이 실행되지만 부모는 그렇지 않습니다.) 그런 다음 execv을 호출하여 sshfs을 루트 권한으로 실행합니다.

자식의 seteuid 호출은 부모 프로세스에 영향을 미치지 않습니다 (execv 이전에 동일한 코드가 실행 중이지만).

execv이 반환되지 않으므로 다시 권한을 삭제할 필요가 없습니다. sshfs이 완료되면 해당 프로세스가 종료됩니다. execv이 실패하면 _exit을 호출하기 전에 권한을 삭제하고 오류 메시지를 인쇄합니다.

관련 문제