最近正在看《容器与容器云》这本书,根据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;
}