Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3012

kernel-2.6.18-194.11.1.el5.src.rpm

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