From: Oleg Nesterov <oleg@redhat.com> Date: Mon, 8 Jun 2009 22:23:39 +0200 Subject: [ptrace] fix do_coredump vs ptrace_start() deadlock Message-id: 20090608202339.GA19971@redhat.com O-Subject: [RHEL5 PATCH] BZ#504263: fix do_coredump() vs ptrace_start() deadlock Bugzilla: 504157 RH-Acked-by: Roland McGrath <roland@redhat.com> CVE: CVE-2009-1388 See https://bugzilla.redhat.com/show_bug.cgi?id=504263 ptrace_start() spins waiting for child->state == TASK_TRACED/TASK_STOPPED. If we race with the coredumping, we have to wait until it completes. If the tracer participates in coredumping too, we deadlock. do_coredump() waits for tracer to exit and report complete(mm->core_startup_done), the tracer spins in an endless loop. Change ptrace_start() to abort if child->mm->core_waiters != 0. Tested with https://bugzilla.redhat.com/attachment.cgi?id=346616, the kernel survives. Although Eugene reports he can't reproduce the bug without the patch too, I think it is clear the bug does exist. Signed-off-by: Oleg Nesterov <oleg@redhat.com> diff --git a/kernel/ptrace.c b/kernel/ptrace.c index c21c32a..edaccb7 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -937,6 +937,15 @@ ptrace_start(long pid, long request, __ptrace_state_free(state); goto out_tsk; } + + task_lock(child); + if (child->mm && child->mm->core_waiters) { + task_unlock(child); + __ptrace_state_free(state); + goto out_tsk; + } + task_unlock(child); + /* * This is a dismal kludge, but it only comes up on ia64. * It might be blocked inside regset->writeback() called