Merge pull request #142 from laijs/enter-sandbox

enter the sandbox when hyper_setup_container_rootfs()
This commit is contained in:
Gao feng
2016-08-02 22:30:03 +08:00
committed by GitHub
6 changed files with 99 additions and 151 deletions
+7 -2
View File
@@ -269,8 +269,8 @@ static int container_setup_mount(struct hyper_container *container)
hyper_mkdir("./dev", 0755);
hyper_mkdir("./lib/modules", 0755);
// mount proc filesystem when the container init process running in the pidns of podinit
if (mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
if (mount("proc", "./proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 ||
mount("devtmpfs", "./dev", "devtmpfs", MS_NOSUID, NULL) < 0) {
perror("mount basic filesystem for container failed");
return -1;
@@ -512,6 +512,11 @@ static int hyper_setup_container_rootfs(void *data)
int setup_dns;
uint32_t type;
if (hyper_enter_sandbox(arg->pod, -1) < 0) {
perror("enter sandbox failed");
goto fail;
}
if (hyper_rescan_scsi() < 0) {
fprintf(stdout, "rescan scsi failed\n");
goto fail;
+20 -94
View File
@@ -8,7 +8,6 @@
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/mount.h>
#include <dirent.h>
#include <sched.h>
#include <errno.h>
@@ -24,6 +23,9 @@
#include "parse.h"
#include "syscall.h"
static int hyper_release_exec(struct hyper_exec *, struct hyper_pod *);
static void hyper_exec_process(struct hyper_exec *exec);
static int send_exec_finishing(uint64_t seq, int len, int code, int block)
{
struct hyper_buf *buf = &ctl.tty.wbuf;
@@ -202,7 +204,7 @@ struct hyper_event_ops err_ops = {
/* don't need write buff, the stderr data is one way */
};
int hyper_setup_exec_user(struct hyper_exec *exec)
static int hyper_setup_exec_user(struct hyper_exec *exec)
{
char *user = exec->user == NULL || strlen(exec->user) == 0 ? NULL : exec->user;
char *group = exec->group == NULL || strlen(exec->group) == 0 ? NULL : exec->group;
@@ -333,7 +335,7 @@ static int hyper_setup_exec_notty(struct hyper_exec *e)
return 0;
}
int hyper_setup_exec_tty(struct hyper_exec *e)
static int hyper_setup_exec_tty(struct hyper_exec *e)
{
int unlock = 0;
int ptymaster;
@@ -410,7 +412,7 @@ int hyper_setup_exec_tty(struct hyper_exec *e)
return 0;
}
int hyper_dup_exec_tty(struct hyper_exec *e)
static int hyper_dup_exec_tty(struct hyper_exec *e)
{
int ret = -1;
@@ -457,7 +459,7 @@ out:
return ret;
}
int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod)
static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod)
{
fprintf(stdout, "hyper_init_event container pts event %p, ops %p, fd %d\n",
&exec->stdinev, &in_ops, exec->stdinev.fd);
@@ -488,47 +490,27 @@ 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) {
@@ -536,59 +518,6 @@ 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);
@@ -599,15 +528,12 @@ 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
void hyper_exec_process(struct hyper_exec *exec)
static void hyper_exec_process(struct hyper_exec *exec)
{
if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) {
perror("sigprocmask restore mask failed");
@@ -624,7 +550,7 @@ 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;
@@ -773,8 +699,8 @@ out:
return ret;
}
int hyper_release_exec(struct hyper_exec *exec,
struct hyper_pod *pod)
static int hyper_release_exec(struct hyper_exec *exec,
struct hyper_pod *pod)
{
if (--exec->ref != 0) {
fprintf(stdout, "still have %d user of exec\n", exec->ref);
-8
View File
@@ -45,18 +45,10 @@ struct hyper_exec {
struct hyper_pod;
int hyper_exec_cmd(char *json, int length);
int hyper_release_exec(struct hyper_exec *, struct hyper_pod *);
int hyper_container_execcmd(struct hyper_pod *pod);
int hyper_setup_exec_tty(struct hyper_exec *e);
int hyper_dup_exec_tty(struct hyper_exec *e);
int hyper_run_process(struct hyper_exec *e);
void hyper_exec_process(struct hyper_exec *e);
struct hyper_exec *hyper_find_exec_by_pid(struct list_head *head, int pid);
struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq);
int hyper_setup_exec_user(struct hyper_exec *e);
int hyper_handle_exec_exit(struct hyper_pod *pod, int pid, uint8_t code);
int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod);
void hyper_cleanup_exec(struct hyper_pod *pod);
extern struct hyper_event_ops pts_ops;
#endif
+1 -2
View File
@@ -74,7 +74,6 @@ struct portmapping_white_list {
};
struct hyper_win_size {
char *tty;
int row;
int column;
uint64_t seq;
@@ -119,8 +118,8 @@ static inline int hyper_create(char *hyper_path)
}
int hyper_open_serial(char *tty);
int hyper_start_containers(struct hyper_pod *pod);
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;
+65 -31
View File
@@ -44,13 +44,10 @@ static int hyper_stop_pod(struct hyper_pod *pod);
static int hyper_set_win_size(char *json, int length)
{
struct hyper_win_size ws = {
.tty = NULL,
};
struct hyper_win_size ws;
struct winsize size;
struct hyper_exec *exec;
char path[128];
int fd, ret;
int ret;
fprintf(stdout, "call hyper_win_size, json %s, len %d\n", json, length);
if (hyper_parse_winsize(&ws, json, length) < 0) {
@@ -58,39 +55,19 @@ static int hyper_set_win_size(char *json, int length)
return -1;
}
if (!ws.tty) {
exec = hyper_find_exec_by_seq(&global_pod, ws.seq);
if (exec == NULL) {
fprintf(stdout, "can not find exec whose seq is %" PRIu64"\n", ws.seq);
return 0;
}
fprintf(stdout, "find exec %s, pid is %d, seq is %" PRIu64"\n",
exec->id ? exec->id : "pod", exec->pid, ws.seq);
fd = dup(exec->ptyfd);
} else {
if (sprintf(path, "/dev/%s", ws.tty) < 0) {
fprintf(stderr, "get tty device failed\n");
return -1;
}
fd = hyper_open_serial_dev(path);
}
if (fd < 0) {
perror("cannot open pty device to set term size");
goto out;
exec = hyper_find_exec_by_seq(&global_pod, ws.seq);
if (exec == NULL) {
fprintf(stdout, "can not find exec whose seq is %" PRIu64"\n", ws.seq);
return 0;
}
size.ws_row = ws.row;
size.ws_col = ws.column;
ret = ioctl(fd, TIOCSWINSZ, &size);
ret = ioctl(exec->ptyfd, TIOCSWINSZ, &size);
if (ret < 0)
perror("cannot ioctl to set pty device term size");
close(fd);
out:
free(ws.tty);
return ret;
}
@@ -275,7 +252,7 @@ fail:
goto out;
}
int hyper_start_containers(struct hyper_pod *pod)
static int hyper_start_containers(struct hyper_pod *pod)
{
struct hyper_container *c;
@@ -349,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
+6 -14
View File
@@ -1292,28 +1292,24 @@ realloc:
continue;
if (i++ == n)
goto fail;
goto out;
if (json_token_streq(json, t, "tty")) {
if (toks[i].type != JSMN_STRING)
goto fail;
ws->tty = (json_token_str(json, &toks[i]));
} else if (json_token_streq(json, t, "seq")) {
if (json_token_streq(json, t, "seq")) {
if (toks[i].type != JSMN_PRIMITIVE)
goto fail;
goto out;
ws->seq = json_token_ll(json, &toks[i]);
} else if (json_token_streq(json, t, "row")) {
if (toks[i].type != JSMN_PRIMITIVE)
goto fail;
goto out;
ws->row = json_token_int(json, &toks[i]);
} else if (json_token_streq(json, t, "column")) {
if (toks[i].type != JSMN_PRIMITIVE)
goto fail;
goto out;
ws->column = json_token_int(json, &toks[i]);
} else {
fprintf(stderr, "get unknown section %s in winsize\n",
json_token_str(json, t));
goto fail;
goto out;
}
}
@@ -1321,10 +1317,6 @@ realloc:
out:
free(toks);
return ret;
fail:
free(ws->tty);
ws->tty = NULL;
goto out;
}
struct hyper_exec *hyper_parse_execcmd(char *json, int length)