diff options
author | Daniel Jacobowitz <drow@sources.redhat.com> | 2009-10-30 01:00:44 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-10-30 01:00:44 -0700 |
commit | 25db0f6ca996f799de308aa2dc7c62caa99ee9dc (patch) | |
tree | 96e757452ac19106c74587f208c02e9e10455398 /nptl/nptl-init.c | |
parent | 31c759bf37a7a41faf8b13800deb769e8a5f3871 (diff) | |
download | glibc-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.c | 16 |
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); } |