Re: [PATCH] fix de_thread() vs do_coredump() deadlock

From: Oleg Nesterov
Date: Mon Apr 10 2006 - 13:43:27 EST


On 04/09, Roland McGrath wrote:
>
> Now, the
> coredump case matches the non-coredump fatal signal: the signal is dropped
> on the floor.

A fatal signal is placed to ->shared_pending in any (non tkill) case, so I
think it is not lost (but may be unnoticed for a while).

sig_kernel_coredump() is different. It could be stealed by one of sub-threads
while another one does de_thread(), that is why it could be lost.

What do you think about something like this untested patch instead?
I am far from sure it is correct, I need a sleep ...

Oleg.

--- fs/exec.c~ 2006-04-10 22:15:06.000000000 +0400
+++ fs/exec.c 2006-04-11 00:56:52.000000000 +0400
@@ -657,6 +657,7 @@ static int de_thread(struct task_struct
}
sig->group_exit_task = NULL;
sig->notify_count = 0;
+ recalc_sigpending();
spin_unlock_irq(lock);

/*
@@ -1478,9 +1479,15 @@ int do_coredump(long signr, int exit_cod
}
mm->dumpable = 0;

- retval = -EAGAIN;
spin_lock_irq(&current->sighand->siglock);
- if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+ if (current->signal->flags & SIGNAL_GROUP_EXIT) {
+ // Re-add the signal. This does not matter
+ // if we are doing do_group_exit().
+ // If it was de_thread(), this signal will be
+ // received again after sys_exec() succeeds.
+ sigaddset(&current->signal->shared_pending.signal, signr);
+ retval = -EAGAIN;
+ } else {
current->signal->flags = SIGNAL_GROUP_EXIT;
current->signal->group_exit_code = exit_code;
current->signal->group_stop_count = 0;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/