Re: [RFC][PATCH 5/7][v4] Protect cinit from blocked fatal signals

Oleg Nesterov
2008-12-24T16:11:56Z

On 12/24, Sukadev Bhattiprolu wrote:
>
> + * So, @signal is for a container-init and if @signr is either SIGKILL or
> + * SIGSTOP, it must have come from an ancestor namespace.

This is wrong. SIGKILL can be sent "internally", for example by
do_group_exit().

> + * If @signal refers to a container-init and @signr is neither SIGKILL nor
> + * SIGSTOP, it was queued because it was blocked when it was posted.

This is not right too. It is possible that init had a handler when
the signal was sent, and the handler was set to SIG_DFL before the
signal was dequeued.

> +static int unkillable_by_sig(struct signal_struct *signal, int signr)
> +{
> + if ((signal->flags & SIGNAL_UNKILLABLE) && !sig_kernel_only(signr))
> + return 1;
> + return 0;
> +}
> +
> int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
> struct pt_regs *regs, void *cookie)
> {
> @@ -1909,9 +1944,11 @@ relock:
>
> /*
> * Global init gets no signals it doesn't want.
> + * Container-init gets no signals it doesn't want from same
> + * container.
> */
> - if (unlikely(signal->flags & SIGNAL_UNKILLABLE) &&
> - !signal_group_exit(signal))
> + if (unkillable_by_sig(signal, signr) &&
> + !signal_group_exit(signal))

No need to check signal_group_exit(signal). It was needed to
handle SIGKILL when it is sent by do_group_exit()/de_thread().
With this patch this is covered by sig_kernel_only().

Personally, I'd prefer to retain this check inline with a small
comment

/* SMALL COMMENT ;) */
if (unlikely(signal->flags & SIGNAL_UNKILLABLE) &&
!sig_kernel_only(signr))
continue;

Oleg.