]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Add fix for bad BUG_ON in de_thread() from Alex Nyberg
authorChris Wright <chrisw@osdl.org>
Thu, 15 Sep 2005 21:27:03 +0000 (14:27 -0700)
committerChris Wright <chrisw@osdl.org>
Thu, 15 Sep 2005 21:27:03 +0000 (14:27 -0700)
queue/fix-de_thread-BUG_ON.patch [new file with mode: 0644]
queue/series

diff --git a/queue/fix-de_thread-BUG_ON.patch b/queue/fix-de_thread-BUG_ON.patch
new file mode 100644 (file)
index 0000000..9b729a3
--- /dev/null
@@ -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 <alexn@telia.com>
+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 <alexn@telia.com>
+Cc: Roland McGrath <roland@redhat.com>
+Cc: Andrew Morton <akpm@osdl.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Acked-by: Andi Kleen <ak@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Chris Wright <chrisw@osdl.org>
+---
+ 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;
+ }
index 001f25683dc6207b533310188bbad2dd753a7aee..b3704c840f3ea419742cb3fc0d4f2e2e64ef75a2 100644 (file)
@@ -1 +1,2 @@
 yenta-oops-fix.patch
+fix-de_thread-BUG_ON.patch