对于Linux用户命名空间,为什么clone()可以挂载/proc,而unshare()却不能?

对于Linux用户命名空间,为什么clone()可以挂载/proc,而unshare()却不能?

我正在尝试让非 root 用户挂载/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

我正在使用 kernel 的 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

相关内容