Re: pidns : PR_SET_PDEATHSIG + SIGKILL regression

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ccing Oleg and Roland.

Serge E. Hallyn [serue@xxxxxxxxxx] wrote:
| Thanks, Daniel, great testcase.

Agree :-)

| 
| Suka, Pavel, the problem is because send_signal() only calls a
| signal from_ancestor_ns if is_si_special(info), while reparent_thread()
| sends SEND_SIG_NOINFO.
| 
| Why is the '!is_si_special(info)' check there for from_ancestor_ns()?

The is_si_special() check is to ensure that we don't affect any signals
that the kernel is generating (such as the SIGKILL when out of memory).
Ensuring that info is not special also makes it safe to check SI_FROMUSER
(which in turn is needed to ensure we are not in interrupt context and
can safely deref 'current' to find the pidns).

Following quick patch seems to fix the problem. But I am not sure if
pdeath_signal needs to be treated as SEND_SIG_NOINFO (does it need to
be special or can we pass in a siginfo like we do when sending SIGCHLD
to parent) ?

| 
| -serge
| 
| Quoting Daniel Lezcano (dlezcano@xxxxxxxxxx):
| > Hi,
| > 
| > I noticed a changed behaviour with the PR_SET_PDEATHSIG and SIGKILL 
| > between different kernel versions.
| > 
| > With a kernel 2.6.27.21-78.2.41.fc9.x86_64, the SIGKILL signal is 
| > delivered to the child process when the parent dies but with a 2.6.31 
| > kernel version that don't happen.
| > 
| > The program below shows the problem. I remember there was were some 
| > modifications about not killing the init process of the container from 
| > inside, but in this case, that happens _conceptually_ from outside. 
| > Keeping this feature is very important to be able to wipe out the 
| > container when the parent process of the container dies.
| > 

(Test case moved to attachment).

Sukadev

---

 kernel/exit.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

Index: linux-2.6/kernel/exit.c
===================================================================
--- linux-2.6.orig/kernel/exit.c	2009-10-02 16:36:47.000000000 -0700
+++ linux-2.6/kernel/exit.c	2009-10-02 17:19:06.000000000 -0700
@@ -738,8 +738,19 @@ static struct task_struct *find_new_reap
 static void reparent_thread(struct task_struct *father, struct task_struct *p,
 				struct list_head *dead)
 {
-	if (p->pdeath_signal)
-		group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
+	struct siginfo info;
+
+	if (p->pdeath_signal) {
+		info.si_signo = p->pdeath_signal;
+		info.si_errno = 0;
+
+		rcu_read_lock();
+		info.si_pid = task_pid_nr_ns(father, task_active_pid_ns(p));
+		info.si_uid = __task_cred(father)->uid;
+		rcu_read_unlock();
+
+		group_send_sig_info(p->pdeath_signal, &info, p);
+	}
 
 	list_move_tail(&p->sibling, &p->real_parent->children);
 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <sys/param.h>
#include <sys/poll.h>
#include <signal.h>
#include <sched.h>

#ifndef CLONE_NEWPID
#  define CLONE_NEWPID            0x20000000
#endif

int child(void *arg)
{
    if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
        perror("prctl");
        return -1;
    }

    sleep(3);
    printf("I should have gone with my parent\n");
    return -1;
}

pid_t clonens(int (*fn)(void *), void *arg, int flags)
{
    long stack_size = sysconf(_SC_PAGESIZE);
     void *stack = alloca(stack_size) + stack_size;
    return clone(fn, stack, flags | SIGCHLD, arg);
}

int main(int argc, char *argv[])
{
    pid_t pid;

    pid = clonens(child, NULL, CLONE_NEWNS|CLONE_NEWPID);
    if (pid < 0) {
        perror("clone");
        return -1;
    }

    /* let the child to be ready, ugly but simple code */
    sleep(1);
    
    return 0;
}
_______________________________________________
Containers mailing list
Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/containers

[Index of Archives]     [Cgroups]     [Netdev]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux