From 5d073f18fd22a9fe7efe3c9ea92bc4ba7507ae1e Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@redhat.com>
Date: Fri, 25 Jun 2010 10:41:17 +0200
Subject: [PATCH] Fix setxid race handling exiting threads

---
 ChangeLog            |  3 +++
 nptl/allocatestack.c | 11 ++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index a072719c7d..04b40d1e8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2010-06-28  Andreas Schwab  <schwab@redhat.com>
 
+	* allocatestack.c (setxid_mark_thread): Ensure that the exiting
+	thread is woken up.
+
 	* elf/Makefile: Add rules to build and run unload8 test.
 	* elf/unload8.c: New file.
 	* elf/unload8mod1.c: New file.
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 831e98e4ce..1ce9ed563d 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -994,7 +994,16 @@ setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
 
       /* If the thread is exiting right now, ignore it.  */
       if ((ch & EXITING_BITMASK) != 0)
-	return;
+	{
+	  /* Release the futex if there is no other setxid in
+	     progress.  */
+	  if ((ch & SETXID_BITMASK) == 0)
+	    {
+	      t->setxid_futex = 1;
+	      lll_futex_wake (&t->setxid_futex, 1, LLL_PRIVATE);
+	    }
+	  return;
+	}
     }
   while (atomic_compare_and_exchange_bool_acq (&t->cancelhandling,
 					       ch | SETXID_BITMASK, ch));