我正在尝试让非 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) 的角色。
比较
CLONE_NEWPID[...] 如果设置了 CLONE_NEWPID,则在新的 PID 命名空间中创建进程。