+ fix-coredump-vs-exec-deadlock.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     Fix coredump vs exec deadlock

has been added to the -mm tree.  Its filename is

     fix-coredump-vs-exec-deadlock.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this


From: David Howells <dhowells@xxxxxxxxxx>

Fix a race between the coredump code and the exec dethreader that causes
the two to deadlock.

The problem is that if both events happen simultaneously (exec and death by
signal) in two different threads, both threads sit there waiting for the
other to die.

This patch makes exec inferior to death by signal, the dethreader for the
former aborting if it detects the latter.

I've also fixed a potential race in which de_thread() was doing a wait
loop, but with the setting of the task state _after_ the loop condition
check.  I've moved the task state set before the check.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
Cc: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx>
Cc: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Roland McGrath <roland@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 fs/exec.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff -puN fs/exec.c~fix-coredump-vs-exec-deadlock fs/exec.c
--- 25/fs/exec.c~fix-coredump-vs-exec-deadlock	Wed Apr 26 14:30:08 2006
+++ 25-akpm/fs/exec.c	Wed Apr 26 14:30:08 2006
@@ -647,10 +647,13 @@ static int de_thread(struct task_struct 
 			hrtimer_restart(&sig->real_timer);
 		spin_lock_irq(lock);
 	}
-	while (atomic_read(&sig->count) > count) {
+	for (;;) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		if (atomic_read(&sig->count) <= count ||
+		    tsk->mm->core_startup_done)
+			break;
 		sig->group_exit_task = current;
 		sig->notify_count = count;
-		__set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_unlock_irq(lock);
 		schedule();
 		spin_lock_irq(lock);
@@ -658,6 +661,13 @@ static int de_thread(struct task_struct 
 	sig->group_exit_task = NULL;
 	sig->notify_count = 0;
 	spin_unlock_irq(lock);
+	__set_current_state(TASK_RUNNING);
+
+	/* exec loses out to death-by-signal in some other thread */
+	if (tsk->mm->core_startup_done) {
+		kmem_cache_free(sighand_cachep, newsighand);
+		return -EINTR;
+	}
 
 	/*
 	 * At this point all other threads have exited, all we have to
@@ -1394,6 +1404,8 @@ static void zap_threads (struct mm_struc
 	do_each_thread(g,p)
 		if (mm == p->mm && p != tsk) {
 			force_sig_specific(SIGKILL, p);
+			/* make sure de_thread() gets the message */
+			wake_up_state(p, TASK_UNINTERRUPTIBLE);
 			mm->core_waiters++;
 			if (unlikely(p->ptrace) &&
 			    unlikely(p->parent->mm == mm))
_

Patches currently in -mm which might be from dhowells@xxxxxxxxxx are

fix-coredump-vs-exec-deadlock.patch
fix-incorrect-sa_onstack-behaviour-for-64-bit-processes.patch
net-rxrpc-use-list_move.patch
fs-use-list_move.patch
mutex-subsystem-synchro-test-module.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux