#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include "util.h" struct params { char* shared_folder; int fd[2]; char **argv; }; struct limits { size_t memory; int core; }; #include "ns_exec.c" #include "cgroup_prepare.c" //const size_t STACK_SIZE=1000000; #define STACK_SIZE 1000000 static char nmstack[STACK_SIZE]; static void parse_args(int argc, char **argv, struct params *params,struct limits *limits){ if (argc < 5) { printf("usage:\n starter "); exit(0); } argc--;argv++; limits->core=atoi(argv[0]); argc--;argv++; limits->memory=atoi(argv[0]); argc--;argv++; params->shared_folder=argv[0]; argc--;argv++; params->argv = argv; } static void prepare_userns(int pid) { char path[100]; char line[100]; int uid = getuid(); int gid = getgid(); //int unprivileged_uid=1002; //int unprivileged_gid=1002; int unprivileged_uid=66534; int unprivileged_gid=65534; sprintf(path, "/proc/%d/uid_map", pid); sprintf(line, "0 %d 1\n1 %d 1000\n", uid, unprivileged_uid); write_file(path, line); sprintf(path, "/proc/%d/setgroups", pid); sprintf(line, "deny"); write_file(path, line); sprintf(path, "/proc/%d/gid_map", pid); sprintf(line, "0 %d 1\n1 %d 1000\n", gid, unprivileged_gid); write_file(path, line); } int main(int argc,char** argv) { srand(time(NULL)); struct params params; memset(¶ms, 0, sizeof(struct params)); struct limits limits; memset(&limits, 0, sizeof(struct limits)); parse_args(argc, argv, ¶ms, &limits); prepare_cgroup(&limits); //exit(0); if(setuid(0)) die("need to be run as root"); if(setgid(0)) die("need to be run as root"); if (pipe(params.fd) < 0) exit(0); int clone_flags = SIGCHLD | CLONE_NEWUTS | CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWIPC | CLONE_NEWCGROUP/* | CLONE_NEWTIME*/; int nsrun_pid=clone(nsrun,nmstack+STACK_SIZE,clone_flags,¶ms); int pipe=params.fd[1]; //sleep(1); prepare_userns(nsrun_pid); if (nsrun_pid<0) {die("faled to clone");} add_to_cgroup(nsrun_pid); if (write(pipe, "OK", 2) != 2) die("Failed to write to pipe: %m");//report readiness if (waitpid(nsrun_pid, NULL, 0) == -1) die("Failed to wait pid %d: %m\n", nsrun_pid); //int pipe=params.fd[1]; remove_cgroup(); return 0; }