2017-01-10 1 views
5

Linux 시스템 함수 unshare (CLONE_NEWNS)를 호출하면 성공을 나타내는 0이 반환됩니다. 그러나 기대했던대로 작동하지 않는 것 같습니다. 특히 tmpfs와 같은 새로운 마운트를 추가하면 전체적으로 볼 수 있습니다. 따라서 실제로 예상대로 전용 마운트 네임 스페이스가 아닙니다.unshare mount 네임 스페이스가 예상대로 작동하지 않습니다.

다음은이 문제를 보여주는 예제 프로그램입니다. 이것을 컴파일하여 하나의 터미널에서 실행하십시오. 그런 다음 다른 터미널을 열고 예제 프로그램에서 작성한 경로가 표시되는지 확인하십시오. 그것은 그렇게해서는 안됩니다. 그것은 공유하지 않는 통화가 아무 것도하지 않은 것처럼 행동합니다. 내가 예상했던 것은 그 순간부터이 프로그램이 수행 한 후속 마운트가 다른 프로세스에서 볼 수 없게된다는 것입니다.

/* Run this program as root. As mount and unshare requires higher privileges. */ 

#define _GNU_SOURCE 
#include <sched.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <sys/mount.h> 
#include <stdlib.h> 
#include <stdio.h> 

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ 
    } while (0) 

int main(int argc, char *argv[]) 
{ 
    // Create a temporary directory at /tmp/unshare 
    mkdir("/tmp/unshare", S_IRWXG); 
    if (unshare(CLONE_NEWNS) == -1) 
     errExit("unshare"); 

    if (mount("none", "/tmp/unshare", "tmpfs", 0, "mode=0700") == -1) 
     errExit("unshare"); 

    FILE* fp = fopen("/tmp/unshare/test", "w"); 
    fprintf(fp, "This file should not be seen by other processes right?\n"); 
    fclose(fp); 

    // Pause 
    printf("Now open another shell. As the root user, verify the file /tmp/unshare/test is not seen\n.Press enter end finish\n"); 
    char c = getchar(); 

    if (umount("/tmp/unshare") == -1) 
     errExit("umount"); 
} 

필자는 마운트 맨 페이지가 이것이 작동해야한다고 제안합니다. 특히 "프로세스 별 네임 스페이스"라는 레이블이 붙은 섹션. 당신이 공유 해제 터미널 명령을 사용하면

A process can obtain a private mount namespace if ... 
it calls unshare(2) with the CLONE_NEWNS flag, which 
causes the caller's mount namespace to obtain a private copy of the 
namespace that it was previously sharing with other processes, so that 
future mounts and unmounts by the caller are invisible to other pro‐ 
cesses (except child processes that the caller subsequently creates) 
and vice versa. 

, 그것을 작동합니다. 그러나 이것은 또 다른 과정을 만들어냅니다. 그러나 man 페이지는 unshare 시스템 호출을 사용할 때 포킹이나 복제 할 필요가 없음을 시사합니다. 여기서 내가 뭘 잘못하고 있니?

+0

스택 오버플로는 프로그래밍 및 개발 관련 질문 용 사이트입니다. 이 질문은 프로그래밍이나 개발에 관한 것이 아니기 때문에 주제와는 거리가 먼 것처럼 보입니다. 도움말 센터에서 [여기에서 내가 질문 할 수있는 항목은 무엇입니까?] (http://stackoverflow.com/help/on-topic)를 참조하십시오. 아마도 [Super User] (http://superuser.com/) 나 [Unix & Linux Stack Exchange] (http://unix.stackexchange.com/)가 더 나은 곳이 될 것입니다. [Dev Ops에 관한 질문은 어디에 게시합니까?] (http://meta.stackexchange.com/q/134306) – jww

+3

Dude, unshare (CLONE_NEWNS)는 C 호출입니다! 이것은 리눅스 API를 사용하고 있습니다. 화제는 무엇을 의미합니까? C에서 작업하려면이 파일이 필요합니다. – Matt

+0

어떻게 파일 시스템을 마운트합니까? 프로그램이 종료 된 후 동일한 프로그램 또는 쉘에서? – immibis

답변

3

strace를 실행 한 후에 대답을 찾았습니다.

\> strace unmount -m true 
... 
unshare(CLONE_NEWNS)     = 0 
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0 
execve("/home/matt/.nvm/versions/node/v6.9.1/bin/true", ["true"], [/* 29 vars */]) = -1 ENOENT (No such file or directory) 
... 

공유 해제에 이어지는 마운트에 유의하십시오. 이 마운트 호출은 마운트에 대한 모든 후속 변경 사항을 재귀 적으로 개인용으로 표시합니다. 그리고이 샌드 박스 코드를 살펴보면 : https://github.com/swetland/mkbox 저자는 그 일을하고 있습니다.

여기 작업 버전이 있습니다.

/* Run this program as root. As mount and unshare requires higher privileges. */ 

#define _GNU_SOURCE 
#include <sched.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <sys/mount.h> 
#include <stdlib.h> 
#include <stdio.h> 

#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ 
    } while (0) 

int main(int argc, char *argv[]) 
{ 
    // Create a temporary directory at /tmp/unshare 
    mkdir("/tmp/unshare", S_IRWXG); 
    if (unshare(CLONE_NEWNS | CLONE_FS | CLONE_THREAD) == -1) 
     errExit("unshare"); 

    /* ensure that changes to our mount namespace do not "leak" to 
    * outside namespaces (what mount --make-rprivate/does) 
    */ 
    if (mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) == -1) 
     errExit("mount1"); 

    if (mount("none", "/tmp/unshare", "tmpfs", 0, NULL) == -1) 
     errExit("mount2"); 

    // if (mount("none", "/tmp/unshare", NULL, MS_PRIVATE, NULL) == -1) 
    // errExit("mount2"); 

    FILE* fp = fopen("/tmp/unshare/test", "w"); 
    fprintf(fp, "This file should not be seen\n"); 
    fclose(fp); 

    // Pause 
    printf("Now open another shell. As the root user, verify the file /tmp/unshare/test is not seen\n.Press enter end finish\n"); 
    char c = getchar(); 

    if (umount("/tmp/unshare") == -1) 
     errExit("umount"); 
} 
관련 문제