qq_33870195 2019-12-30 16:30 采纳率: 0%
浏览 264

linux namespace隔离问题

最近正在看《容器与容器云》这本书,根据3.1的代码想自己实现一个隔离所有6种命名空间的简易沙盒,代码如下,基本是照书抄的。

问题是:我做了PID隔离之后子进程的shell pid和外部隔离了,getpid()获取到的值是1,然后子进程就去改/proc/1下的文件了,这当然是改不了的,问题是在子进程中怎么能获取外部进程中所对应的pid呢,用getppid也不行,有没有什么好的办法。

#define _GNU_SOURCE

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sys/capability.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

#define STACK_SIZE (1024*1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = {"/bin/bash", NULL};

void set_uid_map(pid_t pid, int inside_id, int outside_id, int length){
   char path[256];
   sprintf(path, "/proc/%d/uid_map", pid);
   FILE* uid_map = fopen(path, "w");
   fprintf(uid_map, "%d %d %d", inside_id, outside_id, length);
   fclose(uid_map);
}

void set_gid_map(pid_t pid, int inside_id, int outside_id, int length){
   char path[256];
   sprintf(path, "/proc/%d/gid_map", pid);
   FILE* gid_map = fopen(path, "w");
   fprintf(gid_map, "%d %d %d", inside_id, outside_id, length);
   fclose(gid_map);
}

int child_main(void * args) {
   printf("in child process\n");
   cap_t caps;
   set_uid_map(getpid(), 0, 1000, 1);
   set_gid_map(getpid(), 0, 1000, 1);
   printf("eUID = %ld; eGID = %ld; ", (long) geteuid(), (long) getegid());
   caps = cap_get_proc();
   printf("capabilities: %s\n", cap_to_text(caps, NULL));
   execv(child_args[0], child_args);
   printf("quit child process…\n");
   return 1;
}
int main()
{
    printf("starting process...\n");
    int child_pid = clone(child_main, child_stack + STACK_SIZE,
                          CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWNET|CLONE_NEWNS|CLONE_NEWUSER|SIGCHLD,
                          NULL);
    if(child_pid == -1)
    {
        printf("error starting child process...\n");
    }
    waitpid(child_pid, NULL, 0);
    printf("quit process...\n");
    return 0;
}
  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-27 16:34
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    在Linux中,每个进程都有自己的独立的环境,包括其自身的用户 ID(eUID)、组 ID(eGID)以及各种权限。但是,由于系统资源的限制,无法将多个进程分配到同一块内存区域中,因此不能共享它们的内部变量。

    在你的代码中,你尝试通过设置uid_mapgid_map来模拟一个进程之间的身份隔离。这些方法可以用来跟踪进程的用户和组 ID,从而提供一些额外的信息关于进程的身份。

    然而,这并不足以确保两个进程之间不会相互访问对方的内核数据结构。例如,即使设置了uid_mapgid_map,也无法阻止两个进程访问对方的/proc/<pid>/status/proc/<pid>/fd文件。这是因为这些文件的内容是由内核管理的,并且不是由进程直接控制的。

    要解决这个问题,你需要使用更高级的方法,比如使用信号处理或者进程间通信(IPC)。例如,在Unix环境中,你可以使用IPC_CREAT标志创建一个新的文件描述符,这样两个进程就可以安全地共享这个文件。如果你使用的是Windows,则可能需要使用管道、消息队列等其他形式的IPC机制。

    此外,如果想要更精确地隔离进程,你可能还需要考虑更多的因素,比如进程上下文切换时间、内存分配策略等等。

    评论

报告相同问题?

悬赏问题

  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法
  • ¥15 dnat基础问题,本机发出,别人返回的包,不能命中
  • ¥15 请各位帮我看看是哪里出了问题