Define/use siginfo_from_ancestor_ns
Subsystems (3)
RFC PATCH 1/1 Define/use siginfo_from_ancestor_ns
Quick patch implementing Oleg's suggestion. Touch tested and seems to work fine in preventing container-init from being terminated from within namespace.
---
From: Sukadev Bhattiprolu <[email protected]>
Date: Mon, 10 Nov 2008 17:16:02 -0800
Subject: [PATCH] Define/use siginfo_from_ancestor_ns()
Container-init must appear like 'global-init' to processes within the container and hence it must be immune to fatal signals from within the container. But container-init should appear like a normal process to processes in ancestor namespaces and so if same fatal signal is sent by a process in parent namespace, the container-init must terminate.
There have been several attempts to meet these conflicting requirements This patch (tries to) implement the approach suggested recently by Oleg Nesterov.
Touch tested, but this is just a quick patch with couple of known issues.
TODO:
- We need additional checks for stopped/traced processes.
- If fatal signal is simultaneously received from descendant and ancestor namespaces (in that order), the signal from ancestor maybe ignored
- sys_rt_sigqueueinfo() will fail if user-space sets si_pid to 0.
Signed-off-by <[email protected]>
--- kernel/fork.c | 1 + kernel/signal.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletions(-)
kernel/fork.c +1 -0
@@ -1117,6 +1117,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,if (clone_flags &CLONE_NEWPID ) { retval =pid_ns_prepare_proc (p->nsproxy->pid_ns); + p->signal->flags |=SIGNAL_UNKILLABLE ;if (retval <0 ) goto bad_fork_free_pid; }
kernel/signal.c +6 -1
@@ -1742,6 +1742,10 @@ static int ptrace_signal(int signr, siginfo_t *info,return signr; } +static inline int siginfo_from_ancestor_ns (siginfo_t *info) +{ +return SI_FROMUSER (info) && (info->si_pid ==0 ); +}int get_signal_to_deliver (siginfo_t *info,struct k_sigaction *return_ka,struct pt_regs *regs,void *cookie) {
@@ -1835,7 +1839,8 @@ relock:* Global init gets no signals it doesn't want. */ if (unlikely (signal->flags &SIGNAL_UNKILLABLE ) && - !signal_group_exit (signal)) + !siginfo_from_ancestor_ns (info) && + !signal_group_exit (signal))continue ;if (sig_kernel_stop (signr)) {
Signature · 1 line
1.5.2.5
A message that is not in the archive (sent off-list or not yet received): 20081112070535.GA28136-r/[email protected]
kernel/fork.c static struct task_struct *copy_process(unsigned long clone_flags, · line 1120
Quoted 8 lines · Sukadev Bhattiprolu
kernel/fork.c +1
-0@@ -1117,6 +1117,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,if (clone_flags &CLONE_NEWPID ) { retval =pid_ns_prepare_proc (p->nsproxy->pid_ns); + p->signal->flags |=SIGNAL_UNKILLABLE ;
Minor nit... up to you, but perhaps this should go into copy_signal().
Oleg.