From 74f6930073fe18272e6adf77a7967f9580fe1d0c Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 2 Aug 2016 11:06:47 +0800 Subject: [PATCH] add hyper_enter_sandbox() Signed-off-by: Lai Jiangshan --- src/exec.c | 90 ++++++----------------------------------------------- src/hyper.h | 1 + src/init.c | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 80 deletions(-) diff --git a/src/exec.c b/src/exec.c index 03cc4d6..d2213a2 100644 --- a/src/exec.c +++ b/src/exec.c @@ -491,47 +491,27 @@ static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod) return 0; } -static int hyper_enter_container(struct hyper_pod *pod, - struct hyper_exec *exec) +static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe) { - int ipcns, utsns, mntns, ret; struct hyper_container *c; - char path[512]; - ret = ipcns = utsns = mntns = -1; + if (hyper_enter_sandbox(pod, pipe) < 0) { + perror("enter pidns of pod init failed"); + hyper_send_type(pipe, -1); + goto out; + } c = hyper_find_container(pod, exec->id); if (c == NULL) { fprintf(stderr, "can not find container %s\n", exec->id); - return -1; - } - - sprintf(path, "/proc/%d/ns/uts", pod->init_pid); - utsns = open(path, O_RDONLY| O_CLOEXEC); - if (utsns < 0) { - perror("fail to open utsns of pod init"); goto out; } - sprintf(path, "/proc/%d/ns/ipc", pod->init_pid); - ipcns = open(path, O_RDONLY| O_CLOEXEC); - if (ipcns < 0) { - perror("fail to open ipcns of pod init"); - goto out; - } - - mntns = c->ns; - if (mntns < 0) { - perror("fail to open mntns of pod init"); - goto out; - } - - if (setns(utsns, CLONE_NEWUTS) < 0 || - setns(ipcns, CLONE_NEWIPC) <0 || - setns(mntns, CLONE_NEWNS) < 0) { + if (setns(c->ns, CLONE_NEWNS) < 0) { perror("fail to enter container ns"); goto out; } + chdir("/"); /* TODO: merge container env to exec env in hyperd */ if (hyper_setup_env(c->exec.envs, c->exec.envs_num) < 0) { @@ -539,59 +519,12 @@ static int hyper_enter_container(struct hyper_pod *pod, goto out; } - /* TODO: wait for container finishing setup root */ - chdir("/"); - /* already in pidns & mntns of container, mount proc filesystem */ if (exec->init && mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0) { perror("fail to mount proc filesystem for container"); goto out; } - ret = 0; -out: - close(ipcns); - close(utsns); - - return ret; -} - -static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe) -{ - int pid = -1, ret = -1; - char path[512]; - int pidns; - - sprintf(path, "/proc/%d/ns/pid", pod->init_pid); - pidns = open(path, O_RDONLY| O_CLOEXEC); - if (pidns < 0) { - perror("fail to open pidns of pod init"); - goto out; - } - - /* enter pidns of pod init, so the children of this process will run in - * pidns of pod init, see man 2 setns */ - if (setns(pidns, CLONE_NEWPID) < 0) { - perror("enter pidns of pod init failed"); - goto out; - } - close(pidns); - - pid = fork(); - if (pid < 0) { - perror("fail to fork"); - goto out; - } else if (pid > 0) { - fprintf(stdout, "create exec cmd %s pid %d,ref %d\n", exec->argv[0], pid, exec->ref); - ret = 0; - goto out; - } - - if (hyper_enter_container(pod, exec) < 0) { - fprintf(stderr, "enter container ns failed\n"); - goto exit; - } - // set early env. the container env config can overwrite it setenv("HOME", "/root", 1); setenv("HOSTNAME", pod->hostname, 1); @@ -602,11 +535,8 @@ static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int hyper_exec_process(exec); -exit: - _exit(125); out: - hyper_send_type(pipe, pid); - _exit(ret); + _exit(125); } // do the exec, no return @@ -627,7 +557,7 @@ static void hyper_exec_process(struct hyper_exec *exec) goto exit; } - // set the container env + // set the process env if (hyper_setup_env(exec->envs, exec->envs_num) < 0) { fprintf(stderr, "setup env failed\n"); goto exit; diff --git a/src/hyper.h b/src/hyper.h index eb7b547..2e09966 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -119,6 +119,7 @@ static inline int hyper_create(char *hyper_path) int hyper_open_serial(char *tty); void hyper_cleanup_pod(struct hyper_pod *pod); +int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe); extern struct hyper_pod global_pod; extern struct hyper_ctl ctl; diff --git a/src/init.c b/src/init.c index f1c59f4..61bfe5c 100644 --- a/src/init.c +++ b/src/init.c @@ -326,6 +326,63 @@ out: return ret; } +// enter the sanbox and pass to the child, shouldn't call from the init process +int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe) +{ + int ret = -1, pidns = -1, utsns = -1, ipcns = -1; + char path[512]; + + sprintf(path, "/proc/%d/ns/pid", pod->init_pid); + pidns = open(path, O_RDONLY| O_CLOEXEC); + if (pidns < 0) { + perror("fail to open pidns of pod init"); + goto out; + } + + sprintf(path, "/proc/%d/ns/uts", pod->init_pid); + utsns = open(path, O_RDONLY| O_CLOEXEC); + if (utsns < 0) { + perror("fail to open utsns of pod init"); + goto out; + } + + sprintf(path, "/proc/%d/ns/ipc", pod->init_pid); + ipcns = open(path, O_RDONLY| O_CLOEXEC); + if (ipcns < 0) { + perror("fail to open ipcns of pod init"); + goto out; + } + + if (setns(pidns, CLONE_NEWPID) < 0 || + setns(utsns, CLONE_NEWUTS) < 0 || + setns(ipcns, CLONE_NEWIPC) < 0) { + perror("fail to enter the sandbox"); + goto out; + } + + /* current process isn't in the pidns even setns(pidns, CLONE_NEWPID) + * was called. fork() is needed, so that the child process will run in + * the pidns, see man 2 setns */ + ret = fork(); + if (ret < 0) { + perror("fail to fork"); + goto out; + } else if (ret > 0) { + fprintf(stdout, "create child process pid=%d in the sandbox\n", ret); + if (pidpipe > 0) { + hyper_send_type(pidpipe, ret); + } + _exit(0); + } + +out: + close(pidns); + close(ipcns); + close(utsns); + + return ret; +} + #ifdef WITH_VBOX #define MAX_HOST_NAME 256