about summary refs log tree commit diff
path: root/src/env
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-04-26 15:47:44 -0400
committerRich Felker <dalias@aerifal.cx>2013-04-26 15:47:44 -0400
commit23f21c304fd6a7592b70927e247129c5a2bc2390 (patch)
tree0fab3bbf2287cde6d13c38c594a5901bc85cd330 /src/env
parenta0473a0c826016aec1181819fcd4fff5c074f042 (diff)
downloadmusl-23f21c304fd6a7592b70927e247129c5a2bc2390.tar.gz
musl-23f21c304fd6a7592b70927e247129c5a2bc2390.tar.xz
musl-23f21c304fd6a7592b70927e247129c5a2bc2390.zip
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.
Diffstat (limited to 'src/env')
0 files changed, 0 insertions, 0 deletions