From: Alexander Nyberg Date: Wed, 14 Sep 2005 16:54:06 +0000 (+0200) Subject: [PATCH] Fix fs/exec.c:788 (de_thread()) BUG_ON X-Git-Tag: v2.6.14-rc2~37 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb085cf1d4294824571815d487daccc0609543f0;p=linux-2.6 [PATCH] Fix fs/exec.c:788 (de_thread()) BUG_ON It turns out that the BUG_ON() in fs/exec.c: de_thread() is unreliable and can trigger due to the test itself being racy. de_thread() does while (atomic_read(&sig->count) > count) { } ..... ..... BUG_ON(!thread_group_empty(current)); but release_task does write_lock_irq(&tasklist_lock) __exit_signal (this is where atomic_dec(&sig->count) is run) __exit_sighand __unhash_process takes write lock on tasklist_lock remove itself out of PIDTYPE_TGID list write_unlock_irq(&tasklist_lock) so there's a clear (although small) window between the atomic_dec(&sig->count) and the actual PIDTYPE_TGID unhashing of the thread. And actually there is no need for all threads to have exited at this point, so we simply kill the BUG_ON. Big thanks to Marc Lehmann who provided the test-case. Fixes Bug 5170 (http://bugme.osdl.org/show_bug.cgi?id=5170) Signed-off-by: Alexander Nyberg Cc: Roland McGrath Cc: Andrew Morton Cc: Ingo Molnar Acked-by: Andi Kleen Signed-off-by: Linus Torvalds --- diff --git a/fs/exec.c b/fs/exec.c index 14dd03907c..6fae59a22b 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -745,8 +745,8 @@ static inline int de_thread(struct task_struct *tsk) } /* - * Now there are really no other threads at all, - * so it's safe to stop telling them to kill themselves. + * There may be one thread left which is just exiting, + * but it's safe to stop telling the group to kill themselves. */ sig->flags = 0; @@ -785,7 +785,6 @@ no_thread_group: kmem_cache_free(sighand_cachep, oldsighand); } - BUG_ON(!thread_group_empty(current)); BUG_ON(!thread_group_leader(current)); return 0; }