start: handle setting death signal smarter

parent 86952125
...@@ -896,6 +896,32 @@ static int must_drop_cap_sys_boot(struct lxc_conf *conf) ...@@ -896,6 +896,32 @@ static int must_drop_cap_sys_boot(struct lxc_conf *conf)
return 0; 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) static int do_start(void *data)
{ {
int ret; int ret;
...@@ -907,10 +933,7 @@ static int do_start(void *data) ...@@ -907,10 +933,7 @@ static int do_start(void *data)
int devnull_fd = -1; int devnull_fd = -1;
struct lxc_handler *handler = data; struct lxc_handler *handler = data;
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { lxc_sync_fini_parent(handler);
SYSERROR("Failed to set signal mask.");
return -1;
}
/* This prctl must be before the synchro, so if the parent dies before /* 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 * we set the parent death signal, we will detect its death with the
...@@ -918,21 +941,26 @@ static int do_start(void *data) ...@@ -918,21 +941,26 @@ static int do_start(void *data)
* exit before we set the pdeath signal leading to a unsupervized * exit before we set the pdeath signal leading to a unsupervized
* container. * container.
*/ */
ret = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); ret = lxc_set_death_signal(SIGKILL);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL"); 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. */ /* Don't leak the pinfd to the container. */
if (handler->pinfd >= 0) { if (handler->pinfd >= 0) {
close(handler->pinfd); close(handler->pinfd);
} }
if (lxc_sync_wait_parent(handler, LXC_SYNC_STARTUP)) ret = lxc_sync_wait_parent(handler, LXC_SYNC_STARTUP);
return -1; if (ret < 0)
goto out_warn_father;
/* Unshare CLONE_NEWNET after CLONE_NEWUSER. See /* Unshare CLONE_NEWNET after CLONE_NEWUSER. See
* https://github.com/lxc/lxd/issues/1978. * https://github.com/lxc/lxd/issues/1978.
...@@ -980,7 +1008,7 @@ static int do_start(void *data) ...@@ -980,7 +1008,7 @@ static int do_start(void *data)
} }
/* set{g,u}id() clears deathsignal */ /* set{g,u}id() clears deathsignal */
ret = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); ret = lxc_set_death_signal(SIGKILL);
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL"); SYSERROR("Failed to set PR_SET_PDEATHSIG to SIGKILL");
goto out_warn_father; goto out_warn_father;
...@@ -1390,6 +1418,7 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1390,6 +1418,7 @@ static int lxc_spawn(struct lxc_handler *handler)
SYSERROR("Failed to clone a new set of namespaces."); SYSERROR("Failed to clone a new set of namespaces.");
goto out_delete_net; goto out_delete_net;
} }
TRACE("Cloned child process %d", handler->pid);
for (i = 0; i < LXC_NS_MAX; i++) for (i = 0; i < LXC_NS_MAX; i++)
if (flags & ns_info[i].clone_flag) if (flags & ns_info[i].clone_flag)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment