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

标签 c linux namespaces ubuntu-17.04

我在 Ubuntu 17.04 上。

挂载命名空间的单个非特权取消共享有效。您可以尝试使用 unshare(1) 命令:

$ unshare -m -U /bin/sh
#

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

$ 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 手册页和内核 unshare 文档中找到此信息。

是否有允许这样做的系统设置?

我想要实现的目标:

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

第二次取消共享:非特权 chroot。

最佳答案

我在这里有点猜测,但我认为原因是 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)).

关于c - 为什么不允许非特权递归取消共享(CLONE_NEWUSER)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46140088/

相关文章:

reactjs - 错误 TS2694 : Namespace '"react "' has no exported member ' ReactNode', 'DetailedHTMLProps'、 'HTMLAttributes'、 'SyntheticEvent'、 'HTMLProps'

c - 如何使用 fscanf 和数组读取名字和姓氏的文件

c - Realloc 在循环内第 10 次迭代后失败

c - 为什么控件放在 “else”部分?

linux - 为什么 freebsd 上的 libstdc++ 不需要 libc.so 的链接?

linux - 用于外部 LAN 访问的 Apache 配置

c++ - 使用 LASlib 时重新定义 BOOL typedef

c++ - 是否可以在只读模式下连接到内存中的 sqlite 数据库?

c++ - 调用一个函数一段时间

php - Laravel 4 向类添加方法(IoC/命名空间)