Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 74f6930

Browse files
committed
add hyper_enter_sandbox()
Signed-off-by: Lai Jiangshan <[email protected]>
1 parent 0c05c99 commit 74f6930

File tree

3 files changed

+68
-80
lines changed

3 files changed

+68
-80
lines changed

src/exec.c

Lines changed: 10 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -491,107 +491,40 @@ static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod)
491491
return 0;
492492
}
493493

494-
static int hyper_enter_container(struct hyper_pod *pod,
495-
struct hyper_exec *exec)
494+
static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe)
496495
{
497-
int ipcns, utsns, mntns, ret;
498496
struct hyper_container *c;
499-
char path[512];
500497

501-
ret = ipcns = utsns = mntns = -1;
498+
if (hyper_enter_sandbox(pod, pipe) < 0) {
499+
perror("enter pidns of pod init failed");
500+
hyper_send_type(pipe, -1);
501+
goto out;
502+
}
502503

503504
c = hyper_find_container(pod, exec->id);
504505
if (c == NULL) {
505506
fprintf(stderr, "can not find container %s\n", exec->id);
506-
return -1;
507-
}
508-
509-
sprintf(path, "/proc/%d/ns/uts", pod->init_pid);
510-
utsns = open(path, O_RDONLY| O_CLOEXEC);
511-
if (utsns < 0) {
512-
perror("fail to open utsns of pod init");
513-
goto out;
514-
}
515-
516-
sprintf(path, "/proc/%d/ns/ipc", pod->init_pid);
517-
ipcns = open(path, O_RDONLY| O_CLOEXEC);
518-
if (ipcns < 0) {
519-
perror("fail to open ipcns of pod init");
520-
goto out;
521-
}
522-
523-
mntns = c->ns;
524-
if (mntns < 0) {
525-
perror("fail to open mntns of pod init");
526507
goto out;
527508
}
528509

529-
if (setns(utsns, CLONE_NEWUTS) < 0 ||
530-
setns(ipcns, CLONE_NEWIPC) <0 ||
531-
setns(mntns, CLONE_NEWNS) < 0) {
510+
if (setns(c->ns, CLONE_NEWNS) < 0) {
532511
perror("fail to enter container ns");
533512
goto out;
534513
}
514+
chdir("/");
535515

536516
/* TODO: merge container env to exec env in hyperd */
537517
if (hyper_setup_env(c->exec.envs, c->exec.envs_num) < 0) {
538518
fprintf(stderr, "setup container envs for exec failed\n");
539519
goto out;
540520
}
541521

542-
/* TODO: wait for container finishing setup root */
543-
chdir("/");
544-
545522
/* already in pidns & mntns of container, mount proc filesystem */
546523
if (exec->init && mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0) {
547524
perror("fail to mount proc filesystem for container");
548525
goto out;
549526
}
550527

551-
ret = 0;
552-
out:
553-
close(ipcns);
554-
close(utsns);
555-
556-
return ret;
557-
}
558-
559-
static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe)
560-
{
561-
int pid = -1, ret = -1;
562-
char path[512];
563-
int pidns;
564-
565-
sprintf(path, "/proc/%d/ns/pid", pod->init_pid);
566-
pidns = open(path, O_RDONLY| O_CLOEXEC);
567-
if (pidns < 0) {
568-
perror("fail to open pidns of pod init");
569-
goto out;
570-
}
571-
572-
/* enter pidns of pod init, so the children of this process will run in
573-
* pidns of pod init, see man 2 setns */
574-
if (setns(pidns, CLONE_NEWPID) < 0) {
575-
perror("enter pidns of pod init failed");
576-
goto out;
577-
}
578-
close(pidns);
579-
580-
pid = fork();
581-
if (pid < 0) {
582-
perror("fail to fork");
583-
goto out;
584-
} else if (pid > 0) {
585-
fprintf(stdout, "create exec cmd %s pid %d,ref %d\n", exec->argv[0], pid, exec->ref);
586-
ret = 0;
587-
goto out;
588-
}
589-
590-
if (hyper_enter_container(pod, exec) < 0) {
591-
fprintf(stderr, "enter container ns failed\n");
592-
goto exit;
593-
}
594-
595528
// set early env. the container env config can overwrite it
596529
setenv("HOME", "/root", 1);
597530
setenv("HOSTNAME", pod->hostname, 1);
@@ -602,11 +535,8 @@ static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int
602535

603536
hyper_exec_process(exec);
604537

605-
exit:
606-
_exit(125);
607538
out:
608-
hyper_send_type(pipe, pid);
609-
_exit(ret);
539+
_exit(125);
610540
}
611541

612542
// do the exec, no return
@@ -627,7 +557,7 @@ static void hyper_exec_process(struct hyper_exec *exec)
627557
goto exit;
628558
}
629559

630-
// set the container env
560+
// set the process env
631561
if (hyper_setup_env(exec->envs, exec->envs_num) < 0) {
632562
fprintf(stderr, "setup env failed\n");
633563
goto exit;

src/hyper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static inline int hyper_create(char *hyper_path)
119119

120120
int hyper_open_serial(char *tty);
121121
void hyper_cleanup_pod(struct hyper_pod *pod);
122+
int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe);
122123

123124
extern struct hyper_pod global_pod;
124125
extern struct hyper_ctl ctl;

src/init.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,63 @@ static int hyper_setup_pod_init(struct hyper_pod *pod)
326326
return ret;
327327
}
328328

329+
// enter the sanbox and pass to the child, shouldn't call from the init process
330+
int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe)
331+
{
332+
int ret = -1, pidns = -1, utsns = -1, ipcns = -1;
333+
char path[512];
334+
335+
sprintf(path, "/proc/%d/ns/pid", pod->init_pid);
336+
pidns = open(path, O_RDONLY| O_CLOEXEC);
337+
if (pidns < 0) {
338+
perror("fail to open pidns of pod init");
339+
goto out;
340+
}
341+
342+
sprintf(path, "/proc/%d/ns/uts", pod->init_pid);
343+
utsns = open(path, O_RDONLY| O_CLOEXEC);
344+
if (utsns < 0) {
345+
perror("fail to open utsns of pod init");
346+
goto out;
347+
}
348+
349+
sprintf(path, "/proc/%d/ns/ipc", pod->init_pid);
350+
ipcns = open(path, O_RDONLY| O_CLOEXEC);
351+
if (ipcns < 0) {
352+
perror("fail to open ipcns of pod init");
353+
goto out;
354+
}
355+
356+
if (setns(pidns, CLONE_NEWPID) < 0 ||
357+
setns(utsns, CLONE_NEWUTS) < 0 ||
358+
setns(ipcns, CLONE_NEWIPC) < 0) {
359+
perror("fail to enter the sandbox");
360+
goto out;
361+
}
362+
363+
/* current process isn't in the pidns even setns(pidns, CLONE_NEWPID)
364+
* was called. fork() is needed, so that the child process will run in
365+
* the pidns, see man 2 setns */
366+
ret = fork();
367+
if (ret < 0) {
368+
perror("fail to fork");
369+
goto out;
370+
} else if (ret > 0) {
371+
fprintf(stdout, "create child process pid=%d in the sandbox\n", ret);
372+
if (pidpipe > 0) {
373+
hyper_send_type(pidpipe, ret);
374+
}
375+
_exit(0);
376+
}
377+
378+
out:
379+
close(pidns);
380+
close(ipcns);
381+
close(utsns);
382+
383+
return ret;
384+
}
385+
329386
#ifdef WITH_VBOX
330387

331388
#define MAX_HOST_NAME 256

0 commit comments

Comments
 (0)