为什么不允许非特权递归取消共享(CLONE_NEWUSER)?

时间:2017-09-10 11:12:36

标签: c linux namespaces ubuntu-17.04

我在Ubuntu 17.04上。

单个非保留的不共享mount命名空间有效。您可以尝试使用unshare(1)命令:

$ unshare -m -U /bin/sh
#

但不允许在unshare中取消共享:

$ unshare -m -U /bin/sh
# unshare -m -U /bin/sh
unshare: Operation not permitted
#

这是一个基本上会做同样的C程序:

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

int
main(int argc, char *argv[])
{
    if(unshare(CLONE_NEWUSER|CLONE_NEWNS) == -1) {
        perror("unshare");
        return -1;
    }
    if(unshare(CLONE_NEWUSER|CLONE_NEWNS) == -1) {
        perror("unshare2");
        return -1;
    }
    return 0;
}

为什么不允许这样做?我在哪里可以找到关于此的文档?我无法在unshare或clone手册页和内核取消共享文档中找到此信息。

是否有允许此操作的系统设置?

我想要实现的目标:

首先取消共享:我想用自己的版本在系统上屏蔽几个二进制文件。

第二次取消共享:未被保留的chroot。

1 个答案:

答案 0 :(得分:3)

我在这里猜测,但我认为原因是UID映射。为了执行它,必须满足某些条件(来自user_namespaces手册页):

   In  order  for  a process to write to the /proc/[pid]/uid_map (/proc/[pid]/gid_map) file, all of the following require‐
   ments must be met:

   1. The writing process must have the CAP_SETUID (CAP_SETGID) capability in the user namespace of the process pid.

   2. The writing process must either be in the user namespace of the process pid or be in the parent  user  namespace  of
      the process pid.

   3. The mapped user IDs (group IDs) must in turn have a mapping in the parent user namespace.

我相信会发生的是第一次运行时,映射与父UID的映射匹配。但是,它第二次没有,这就失败了系统调用。

来自unshare(2)手册页:

   EPERM  CLONE_NEWUSER was specified in flags, but either the effective user ID or the effective group ID of  the  caller
          does not have a mapping in the parent namespace (see user_namespaces(7)).