Linux 사용자 네임스페이스의 경우 clone()은 /proc를 마운트할 수 있지만 unshare()는 마운트할 수 없는 이유는 무엇입니까?

Linux 사용자 네임스페이스의 경우 clone()은 /proc를 마운트할 수 있지만 unshare()는 마운트할 수 없는 이유는 무엇입니까?

/proc루트가 아닌 사용자가 Linux 사용자 네임스페이스에 마운트되도록 하려고 합니다 .

네임스페이스를 생성하면 clone()마운트할 수 있습니다 /proc.

그러나 네임스페이스 생성을 통과하면 unshare()호출이 mount()실패합니다 Operation not permitted.

mount()네임스페이스가 생성되었을 때와 사용할 때 다르게 동작하는 이유는 무엇 입니까?clone()unshare()

아래 코드는 차이점을 보여줍니다.

#define   _GNU_SOURCE
#include  <errno.h>
#include  <sched.h>
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <unistd.h>
#include  <sys/syscall.h>
#include  <sys/mount.h>
#include  <sys/types.h>
#include  <sys/stat.h>
#include  <sys/wait.h>
#include  <fcntl.h>


#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];    /* Space for child's stack */


void  try  ( const char * msg, int rv )  {
  printf ( "%-8s  %6d  %s\n", msg, rv, strerror ( rv < 0 ? errno : 0 ) );
}


int  child  ( void * arg )  {
  try(  "mount_1",   mount   (  "PROC", "/proc", "proc", 0, NULL  ));
  try(  "umount_1",  umount  (  "/proc"                           ));
  return  0;
}


int  main  ()  {

  int  clone_flags  =  0;

  clone_flags  |=  CLONE_NEWNET;
  clone_flags  |=  CLONE_NEWNS;
  clone_flags  |=  CLONE_NEWPID;
  clone_flags  |=  CLONE_NEWUSER;

  try(  "clone",    clone    (  child, child_stack + STACK_SIZE,
                                clone_flags | SIGCHLD, NULL       ));
  try(  "wait",     wait     (  NULL                              ));
  try(  "unshare",  unshare  (  clone_flags                       ));
  try(  "mount_2",  mount    (  "PROC", "/proc", "proc", 0, NULL  ));

  return  0;

}

산출:

clone      31478  Success
mount_1        0  Success
umount_1       0  Success
wait       31478  Success
unshare        0  Success
mount_2       -1  Operation not permitted

커널을 사용하여 Ubuntu 18.04에서 실행 중입니다 Linux 4.15.0-20-generic. 위 코드를 루트가 아닌 사용자로 실행하고 있습니다.

답변1

나는 당신이 여전히 "잘못된" PID 네임스페이스에 있다고 생각합니다. 이는 procfs 인스턴스를 마운트할 권한이 없음을 의미합니다.

CLONE_NEWPID[...] 호출 프로세스는 새 네임스페이스로 이동되지 않습니다. 호출 프로세스에 의해 생성된 첫 번째 하위 프로세스는 프로세스 ID 1을 가지며 새 네임스페이스에서 init(1) 역할을 맡습니다.

http://man7.org/linux/man-pages/man2/unshare.2.html

비교하다

CLONE_NEWPID[...] CLONE_NEWPID가 설정되면 새 PID 네임스페이스에 프로세스가 생성됩니다.

http://man7.org/linux/man-pages/man2/clone.2.html

관련 정보