Patch "ptrace: fix PTRACE_LISTEN race corrupting task->state" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ptrace: fix PTRACE_LISTEN race corrupting task->state
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ptrace-fix-ptrace_listen-race-corrupting-task-state.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
5402e97af667e35e54177af8f6575518bf251d51Mon Sep 17 00:00:00 2001
From: "[email protected]" <[email protected]>
Date: Fri, 7 Apr 2017 16:04:51 -0700
Subject: ptrace: fix PTRACE_LISTEN race corrupting task->state
From: [email protected] <[email protected]>
commit 5402e97af667e35e54177af8f6575518bf251d51 upstream.
In PT_SEIZED + LISTEN mode STOP/CONT signals cause a wakeup against __TASK_TRACED. If this races with the ptrace_unfreeze_traced at the end of a PTRACE_LISTEN, this can wake the task /after/ the check against __TASK_TRACED, but before the reset of state to TASK_TRACED. This causes it to instead clobber TASK_WAKING, allowing a subsequent wakeup against TRACED while the task is still on the rq wake_list, corrupting it.
Oleg said:
"The kernel can crash or this can lead to other hard-to-debug problems.
In short, "task->state = TASK_TRACED" in ptrace_unfreeze_traced() assumes that nobody else can wake it up, but PTRACE_LISTEN breaks the contract. Obviusly it is very wrong to manipulate task->state if this task is already running, or WAKING, or it sleeps again"
--- kernel/ptrace.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
kernel/ptrace.c +10 -4
@@ -151,11 +151,17 @@ static void ptrace_unfreeze_traced(strucWARN_ON (!task->ptrace || task->parent != current); +/* +* PTRACE_LISTEN can allow ptrace_trap_notify to wake us up remotely. +* Recheck state under the lock to close this race. +*/ spin_lock_irq (&task->sighand->siglock); -if (__fatal_signal_pending (task)) -wake_up_state (task, __TASK_TRACED); -else - task->state =TASK_TRACED ; +if (task->state == __TASK_TRACED) { +if (__fatal_signal_pending (task)) +wake_up_state (task, __TASK_TRACED); +else + task->state =TASK_TRACED ; + }spin_unlock_irq (&task->sighand->siglock); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/ptrace-fix-ptrace_listen-race-corrupting-task-state.patch