|
@@ -184,11 +184,17 @@ static void ptrace_unfreeze_traced(struct task_struct *task)
|
|
|
|
|
|
WARN_ON(!task->ptrace || task->parent != current);
|
|
WARN_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);
|
|
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);
|
|
spin_unlock_irq(&task->sighand->siglock);
|
|
}
|
|
}
|
|
|
|
|