]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
start: handle setting death signal smarter
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 22 Dec 2017 21:52:42 +0000 (22:52 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 2 Jan 2018 00:08:44 +0000 (01:08 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/start.c

index 57c518aa8c23baee37f9fc245fcd960764eaf4f9..85a349923e3f7a6724f87e8ad78372ecac44cb45 100644 (file)
@@ -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)