From: Chris Wright Date: Thu, 15 Sep 2005 21:27:03 +0000 (-0700) Subject: Add fix for bad BUG_ON in de_thread() from Alex Nyberg X-Git-Tag: v2.6.13.2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5a15864e4722663e68ca41d73bb3d69dc3f1dbc0;p=thirdparty%2Fkernel%2Fstable-queue.git Add fix for bad BUG_ON in de_thread() from Alex Nyberg --- diff --git a/queue/fix-de_thread-BUG_ON.patch b/queue/fix-de_thread-BUG_ON.patch new file mode 100644 index 00000000000..9b729a306c2 --- /dev/null +++ b/queue/fix-de_thread-BUG_ON.patch @@ -0,0 +1,70 @@ +From nobody Mon Sep 17 00:00:00 2001 +Subject: [PATCH] Fix fs/exec.c:788 (de_thread()) BUG_ON +From: Alexander Nyberg +Date: Wed Sep 14 18:54:06 2005 +0200 + +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 +Signed-off-by: Chris Wright +--- + fs/exec.c | 5 ++--- + 1 files changed, 2 insertions(+), 3 deletions(-) + +Index: linux-2.6.13.y/fs/exec.c +=================================================================== +--- linux-2.6.13.y.orig/fs/exec.c ++++ linux-2.6.13.y/fs/exec.c +@@ -745,8 +745,8 @@ static inline int de_thread(struct task_ + } + + /* +- * 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; + } diff --git a/queue/series b/queue/series index 001f25683dc..b3704c840f3 100644 --- a/queue/series +++ b/queue/series @@ -1 +1,2 @@ yenta-oops-fix.patch +fix-de_thread-BUG_ON.patch