lkml.org 
[lkml]   [2021]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 108/917] signal: Remove the bogus sigkill_pending in ptrace_stop
    Date
    From: Eric W. Biederman <ebiederm@xmission.com>

    commit 7d613f9f72ec8f90ddefcae038fdae5adb8404b3 upstream.

    The existence of sigkill_pending is a little silly as it is
    functionally a duplicate of fatal_signal_pending that is used in
    exactly one place.

    Checking for pending fatal signals and returning early in ptrace_stop
    is actively harmful. It casues the ptrace_stop called by
    ptrace_signal to return early before setting current->exit_code.
    Later when ptrace_signal reads the signal number from
    current->exit_code is undefined, making it unpredictable what will
    happen.

    Instead rely on the fact that schedule will not sleep if there is a
    pending signal that can awaken a task.

    Removing the explict sigkill_pending test fixes fixes ptrace_signal
    when ptrace_stop does not stop because current->exit_code is always
    set to to signr.

    Cc: stable@vger.kernel.org
    Fixes: 3d749b9e676b ("ptrace: simplify ptrace_stop()->sigkill_pending() path")
    Fixes: 1a669c2f16d4 ("Add arch_ptrace_stop")
    Link: https://lkml.kernel.org/r/87pmsyx29t.fsf@disp2133
    Reviewed-by: Kees Cook <keescook@chromium.org>
    Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    kernel/signal.c | 18 ++++--------------
    1 file changed, 4 insertions(+), 14 deletions(-)

    --- a/kernel/signal.c
    +++ b/kernel/signal.c
    @@ -2169,15 +2169,6 @@ static inline bool may_ptrace_stop(void)
    return true;
    }

    -/*
    - * Return non-zero if there is a SIGKILL that should be waking us up.
    - * Called with the siglock held.
    - */
    -static bool sigkill_pending(struct task_struct *tsk)
    -{
    - return sigismember(&tsk->pending.signal, SIGKILL) ||
    - sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
    -}

    /*
    * This must be called with current->sighand->siglock held.
    @@ -2204,17 +2195,16 @@ static void ptrace_stop(int exit_code, i
    * calling arch_ptrace_stop, so we must release it now.
    * To preserve proper semantics, we must do this before
    * any signal bookkeeping like checking group_stop_count.
    - * Meanwhile, a SIGKILL could come in before we retake the
    - * siglock. That must prevent us from sleeping in TASK_TRACED.
    - * So after regaining the lock, we must check for SIGKILL.
    */
    spin_unlock_irq(&current->sighand->siglock);
    arch_ptrace_stop(exit_code, info);
    spin_lock_irq(&current->sighand->siglock);
    - if (sigkill_pending(current))
    - return;
    }

    + /*
    + * schedule() will not sleep if there is a pending signal that
    + * can awaken the task.
    + */
    set_special_state(TASK_TRACED);

    /*

    \
     
     \ /
      Last update: 2021-11-16 00:32    [W:2.101 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site