aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2005-10-30 18:02:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:25 -0500
commit1291cf4163d21f1b4999d697cbf68d38e7151c28 (patch)
tree0e1c3e3970216c769f91f6077b0e23d47d6fd333
parentf7232056bff5fe2d3bfeab35252a66ebaeb5bbde (diff)
[PATCH] fix de_thread() vs do_coredump() deadlock
de_thread() sends SIGKILL to all sub-threads and waits them to die in 'D' state. It is possible that one of the threads already dequeued coredump signal. When de_thread() unlocks ->sighand->lock that thread can enter do_coredump()->coredump_wait() and cause a deadlock. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/exec.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 6d9521636aaa..10d493fea7ce 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1460,11 +1460,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1460 current->fsuid = 0; /* Dump root private */ 1460 current->fsuid = 0; /* Dump root private */
1461 } 1461 }
1462 mm->dumpable = 0; 1462 mm->dumpable = 0;
1463 init_completion(&mm->core_done); 1463
1464 retval = -EAGAIN;
1464 spin_lock_irq(&current->sighand->siglock); 1465 spin_lock_irq(&current->sighand->siglock);
1465 current->signal->flags = SIGNAL_GROUP_EXIT; 1466 if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
1466 current->signal->group_exit_code = exit_code; 1467 current->signal->flags = SIGNAL_GROUP_EXIT;
1468 current->signal->group_exit_code = exit_code;
1469 retval = 0;
1470 }
1467 spin_unlock_irq(&current->sighand->siglock); 1471 spin_unlock_irq(&current->sighand->siglock);
1472 if (retval) {
1473 up_write(&mm->mmap_sem);
1474 goto fail;
1475 }
1476
1477 init_completion(&mm->core_done);
1468 coredump_wait(mm); 1478 coredump_wait(mm);
1469 1479
1470 /* 1480 /*