nsenter -m -t <pid_of_podman_bash_main_process> bash:失败的权限被拒绝... EACCESS

时间:2020-06-23 12:17:30

标签: linux-kernel namespaces containers

我的目标是在内部学习和了解有关容器如何真正工作的更多信息。

我目前正在运行一个无根的podman容器(以标准用户 ...的身份以podman run -ti ubuntu bash开头),并且我正在使用nsenter工具来探索名称空间维度。我的最初目标是一个接一个地“附加”到各种名称空间,并更好地理解它们如何工作。我对安装命名空间有疑问:

我想了解为什么在同时指定-U(用户名空间)和-m(正在使用的用户名)时可以输入名称空间。

nsenter -U -m -t 5903 

仅在指定安装名称空间时失败

nsenter -m -t 5903
root@o184i122:~# nsenter -m -t 5903

nsenter: failed to execute bash: Permission denied

使用strace,我发现execve()syscall在nsset()syscall之后得到拒绝的权限...

openat(AT_FDCWD, "/proc/5903/ns/mnt", O_RDONLY) = 3
setns(3, CLONE_NEWNS)                   = 0
close(3)                                = 0
execve("/bin/bash", ["-bash"], 0x7fff7d536fa0 /* 31 vars */) = -1 EACCES (Permission denied)

注意:我的主机正在运行ubuntu 20.04、5.4.0-33-通用

更新:我可以复制以下(我相信足够接近)C程序。 小心,我将bash进程的pid硬编码到了podman容器中...

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sched.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

void main(void)
{
  const char* cmd = "/usr/bin/findmnt";
  char *nargv[] = { NULL };
  char *nenviron[] = { NULL };
  int fd;
  struct stat statbuf;
  
  //uncommenting this will make it work//

  /*fd=openat(AT_FDCWD, "/proc/5903/ns/user", O_RDONLY);
    assert(fd!=-1);
    assert(setns(fd, CLONE_NEWUSER)==0);
    close(fd);*/
  
  fd=openat(AT_FDCWD, "/proc/5903/ns/mnt", O_RDONLY);
  assert(fd!=-1);
  assert(setns(fd, CLONE_NEWNS)==0);
  close(fd);

  assert(setuid(0)==0);
  assert(setgid(0)==0);
  
  printf("uid=%d\n",getuid());
  printf("gid=%d\n",getgid());
  
  if (stat(cmd, &statbuf)) {
    perror("stat failed..");
    exit(1);
  }
  
  execve(cmd, nargv , nenviron);
}

在不加入用户名称空间的情况下,stat(“ /”)上的权限被拒绝

0 个答案:

没有答案
相关问题