Skip to content

Commit

Permalink
[PATCH] fix de_thread() vs do_coredump() deadlock
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Oct 31, 2005
1 parent f723205 commit 1291cf4
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1460,11 +1460,21 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
current->fsuid = 0; /* Dump root private */
}
mm->dumpable = 0;
init_completion(&mm->core_done);

retval = -EAGAIN;
spin_lock_irq(&current->sighand->siglock);
current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code;
if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code;
retval = 0;
}
spin_unlock_irq(&current->sighand->siglock);
if (retval) {
up_write(&mm->mmap_sem);
goto fail;
}

init_completion(&mm->core_done);
coredump_wait(mm);

/*
Expand Down

0 comments on commit 1291cf4

Please sign in to comment.