From: Christian Brauner Date: Fri, 22 Dec 2017 21:52:42 +0000 (+0100) Subject: start: handle setting death signal smarter X-Git-Tag: lxc-2.0.10~445 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8560f461950d0e38a02e1a54a5c8cdbb74b2683;p=thirdparty%2Flxc.git start: handle setting death signal smarter Signed-off-by: Christian Brauner --- diff --git a/src/lxc/start.c b/src/lxc/start.c index 57c518aa8..85a349923 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -896,6 +896,32 @@ static int must_drop_cap_sys_boot(struct lxc_conf *conf) return 0; } +static int lxc_set_death_signal(int signal) +{ + int ret; + pid_t ppid; + + ret = prctl(PR_SET_PDEATHSIG, signal, 0, 0, 0); + + /* Check whether we have been orphaned. */ + ppid = (pid_t)syscall(SYS_getppid); + if (ppid == 1) { + pid_t self; + + self = lxc_raw_getpid(); + ret = kill(self, SIGKILL); + if (ret < 0) + return -1; + } + + if (ret < 0) { + SYSERROR("Failed to set PR_SET_PDEATHSIG to %d", signal); + return -1; + } + + return 0; +} + static int do_start(void *data) { int ret; @@ -907,10 +933,7 @@ static int do_start(void *data) int devnull_fd = -1; struct lxc_handler *handler = data; - if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { - SYSERROR("Failed to set signal mask."); - return -1; - } + lxc_sync_fini_parent(handler); /* This prctl must be before the synchro, so if the parent dies before * we set the parent death signal, we will detect its death with the @@ -918,21 +941,26 @@ static int do_start(void *data) * exit before we set the pdeath signal leading to a unsupervized * container. */ - ret = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); + ret = lxc_set_death_signal(SIGKILL); if (ret < 0) { SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL"); - return -1; + goto out_warn_father; } - lxc_sync_fini_parent(handler); + ret = sigprocmask(SIG_SETMASK, &handler->oldmask, NULL); + if (ret < 0) { + SYSERROR("Failed to set signal mask"); + goto out_warn_father; + } /* Don't leak the pinfd to the container. */ if (handler->pinfd >= 0) { close(handler->pinfd); } - if (lxc_sync_wait_parent(handler, LXC_SYNC_STARTUP)) - return -1; + ret = lxc_sync_wait_parent(handler, LXC_SYNC_STARTUP); + if (ret < 0) + goto out_warn_father; /* Unshare CLONE_NEWNET after CLONE_NEWUSER. See * https://github.com/lxc/lxd/issues/1978. @@ -980,7 +1008,7 @@ static int do_start(void *data) } /* set{g,u}id() clears deathsignal */ - ret = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); + ret = lxc_set_death_signal(SIGKILL); if (ret < 0) { SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL"); goto out_warn_father; @@ -1390,6 +1418,7 @@ static int lxc_spawn(struct lxc_handler *handler) SYSERROR("Failed to clone a new set of namespaces."); goto out_delete_net; } + TRACE("Cloned child process %d", handler->pid); for (i = 0; i < LXC_NS_MAX; i++) if (flags & ns_info[i].clone_flag)