Linuxユーザーの名前空間の場合、clone()は/ procをマウントできますが、unshare()はマウントできないのはなぜですか?

Linuxユーザーの名前空間の場合、clone()は/ procをマウントできますが、unshare()はマウントできないのはなぜですか?

/procroot以外のユーザーが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。上記のコードをrootではなくユーザーとして実行しています。

答え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

関連情報