always block signals in pthread_exit before decrementing thread count
authorRich Felker <dalias@aerifal.cx>
Fri, 26 Apr 2013 19:47:44 +0000 (15:47 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 26 Apr 2013 19:47:44 +0000 (15:47 -0400)
commit23f21c304fd6a7592b70927e247129c5a2bc2390
tree0fab3bbf2287cde6d13c38c594a5901bc85cd330
parenta0473a0c826016aec1181819fcd4fff5c074f042
always block signals in pthread_exit before decrementing thread count

the thread count (1+libc.threads_minus_1) must always be greater than
or equal to the number of threads which could have application code
running, even in an async-signal-safe sense. there is at least one
dangerous race condition if this invariant fails to hold: dlopen could
allocate too little TLS for existing threads, and a signal handler
running in the exiting thread could claim the allocated TLS for itself
(via __tls_get_addr), leaving too little for the other threads it was
allocated for and thereby causing out-of-bounds access.

there may be other situations where it's dangerous for the thread
count to be too low, particularly in the case where only one thread
should be left, in which case locking may be omitted. however, all
such code paths seem to arise from undefined behavior, since
async-signal-unsafe functions are not permitted to be called from a
signal handler that interrupts pthread_exit (which is itself
async-signal-unsafe).

this change may also simplify logic in __synccall and improve the
chances of making __synccall async-signal-safe.
src/thread/pthread_create.c