summary refs log tree commit diff
path: root/nptl/nptl-init.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@sources.redhat.com>2009-10-30 01:00:44 -0700
committerUlrich Drepper <drepper@redhat.com>2009-10-30 01:00:44 -0700
commit25db0f6ca996f799de308aa2dc7c62caa99ee9dc (patch)
tree96e757452ac19106c74587f208c02e9e10455398 /nptl/nptl-init.c
parent31c759bf37a7a41faf8b13800deb769e8a5f3871 (diff)
downloadglibc-25db0f6ca996f799de308aa2dc7c62caa99ee9dc.tar.gz
glibc-25db0f6ca996f799de308aa2dc7c62caa99ee9dc.tar.xz
glibc-25db0f6ca996f799de308aa2dc7c62caa99ee9dc.zip
Fix races in setXid implementation.
Diffstat (limited to 'nptl/nptl-init.c')
-rw-r--r--nptl/nptl-init.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 5e9c250ff7..851bab2bf1 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -240,17 +240,23 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
   INTERNAL_SYSCALL_NCS (__xidcmd->syscall_no, err, 3, __xidcmd->id[0],
 			__xidcmd->id[1], __xidcmd->id[2]);
 
-  if (atomic_decrement_val (&__xidcmd->cntr) == 0)
-    lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
-
   /* Reset the SETXID flag.  */
   struct pthread *self = THREAD_SELF;
-  int flags = THREAD_GETMEM (self, cancelhandling);
-  THREAD_SETMEM (self, cancelhandling, flags & ~SETXID_BITMASK);
+  int flags, newval;
+  do
+    {
+      flags = THREAD_GETMEM (self, cancelhandling);
+      newval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+					  flags & ~SETXID_BITMASK, flags);
+    }
+  while (flags != newval);
 
   /* And release the futex.  */
   self->setxid_futex = 1;
   lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
+
+  if (atomic_decrement_val (&__xidcmd->cntr) == 0)
+    lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
 }