lkml.org 
[lkml]   [2019]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 04/35] signal: Always notice exiting tasks
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Eric W. Biederman <ebiederm@xmission.com>

    commit 35634ffa1751b6efd8cf75010b509dcb0263e29b upstream.

    Recently syzkaller was able to create unkillablle processes by
    creating a timer that is delivered as a thread local signal on SIGHUP,
    and receiving SIGHUP SA_NODEFERER. Ultimately causing a loop
    failing to deliver SIGHUP but always trying.

    Upon examination it turns out part of the problem is actually most of
    the solution. Since 2.5 signal delivery has found all fatal signals,
    marked the signal group for death, and queued SIGKILL in every threads
    thread queue relying on signal->group_exit_code to preserve the
    information of which was the actual fatal signal.

    The conversion of all fatal signals to SIGKILL results in the
    synchronous signal heuristic in next_signal kicking in and preferring
    SIGHUP to SIGKILL. Which is especially problematic as all
    fatal signals have already been transformed into SIGKILL.

    Instead of dequeueing signals and depending upon SIGKILL to
    be the first signal dequeued, first test if the signal group
    has already been marked for death. This guarantees that
    nothing in the signal queue can prevent a process that needs
    to exit from exiting.

    Cc: stable@vger.kernel.org
    Tested-by: Dmitry Vyukov <dvyukov@google.com>
    Reported-by: Dmitry Vyukov <dvyukov@google.com>
    Ref: ebf5ebe31d2c ("[PATCH] signal-fixes-2.5.59-A4")
    History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
    Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    kernel/signal.c | 6 ++++++
    1 file changed, 6 insertions(+)

    --- a/kernel/signal.c
    +++ b/kernel/signal.c
    @@ -2225,6 +2225,11 @@ relock:
    goto relock;
    }

    + /* Has this task already been marked for death? */
    + ksig->info.si_signo = signr = SIGKILL;
    + if (signal_group_exit(signal))
    + goto fatal;
    +
    for (;;) {
    struct k_sigaction *ka;

    @@ -2320,6 +2325,7 @@ relock:
    continue;
    }

    + fatal:
    spin_unlock_irq(&sighand->siglock);

    /*

    \
     
     \ /
      Last update: 2019-02-13 19:43    [W:4.157 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site