race condition fix: block all signals before decrementing thread count
authorRich Felker <dalias@aerifal.cx>
Sat, 19 Feb 2011 16:04:36 +0000 (11:04 -0500)
committerRich Felker <dalias@aerifal.cx>
Sat, 19 Feb 2011 16:04:36 +0000 (11:04 -0500)
the existence of a (kernelspace) thread must never have observable
effects after the thread count is decremented. if signals are not
blocked, it could end up handling the signal for rsyscall and
contributing towards the count of threads which have changed ids,
causing a thread to be missed. this could lead to one thread retaining
unwanted privilege level.

this change may also address other subtle race conditions in
application code that uses signals.

src/thread/i386/__unmapself.s
src/thread/pthread_create.c
src/thread/x86_64/__unmapself.s

index 5c674966167a8af11f18fd4df82ef2e833e0e6cf..bcf6e7fe1a7b963beaf69cd09f3e7ca38978319a 100644 (file)
@@ -2,15 +2,6 @@
 .global __unmapself
 .type   __unmapself,%function
 __unmapself:
-       call 1f
-       .long -1
-       .long -1
-1:     popl %ecx
-       xorl %ebx,%ebx
-       xorl %edx,%edx
-       movl $8,%esi
-       movl $175,%eax
-       int $128
        movl $91,%eax
        movl 4(%esp),%ebx
        movl 8(%esp),%ecx
index 7c436957f8e17b33c8ae8a8a9602b82cfe030690..c73c52114074c66d3c04bf44b3cd18a1d2d78341 100644 (file)
@@ -25,6 +25,8 @@ void __pthread_unwind_next(struct __ptcb *cb)
                }
        }
 
+       syscall4(__NR_sigprocmask, SIG_BLOCK, (long)(uint64_t[1]){-1}, 0, 8);
+
        if (!a_fetch_add(&libc.threads_minus_1, -1))
                exit(0);
 
index 59092eaa53fefd472735c3a5c023a3f0ad56787d..d36257d0d67a894f37ee02401b88d50be71cf039 100644 (file)
@@ -3,19 +3,6 @@
 .global __unmapself
 .type   __unmapself,%function
 __unmapself:
-       call 1f         /* glibc ABI compat */
-       .long -1
-       .long -1
-1:      push %rsi       /* save arg2 for munmap */
-       push %rdx       /* save arg3 for munmap */
-       mov %rdi,%rsi   /* rt_sigprocmask() args: move arg1 to rsi */
-       xor %rdi,%rdi
-       xor %rdx,%rdx
-       movq $8,%r10
-       movl $14,%eax   /* __NR_rt_sigprocmask */
-       syscall         /* call rt_sigprocmask(0,arg1,0,8) */
-       pop %rsi        /* munmap() args: reload from stack */
-       pop %rdi
        movl $11,%eax   /* __NR_munmap */
        syscall         /* munmap(arg2,arg3) */
        xor %rdi,%rdi   /* exit() args: always return success */