about summary refs log tree commit diff
path: root/src/internal
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-10-05 10:41:30 -0400
committerRich Felker <dalias@aerifal.cx>2022-10-19 14:01:32 -0400
commit36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf (patch)
treeb47d2641194ff8bbaea800495a6206a3a104748c /src/internal
parent833a469167521040c7ae94f3c990e258e29445f9 (diff)
downloadmusl-36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf.tar.gz
musl-36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf.tar.xz
musl-36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf.zip
fix potential deadlock in dlerror buffer handling at thread exit
ever since commit 8f11e6127fe93093f81a52b15bb1537edc3fc8af introduced
the thread list lock, this has been wrong. initially, it was wrong via
calling free from the context with the thread list lock held. commit
aa5a9d15e09851f7b4a1668e9dbde0f6234abada deferred the unsafe free but
added a lock, which was also unsafe. in particular, it could deadlock
if code holding freebuf_queue_lock was interrupted by a signal handler
that takes the thread list lock.

commit 4d5aa20a94a2d3fae3e69289dc23ecafbd0c16c4 observed that there
was a lock here but failed to notice that it's invalid.

there is no easy solution to this problem with locks; any attempt at
solving it while still using locks would require the lock to be an
AS-safe one (blocking signals on each access to the dlerror buffer
list to check if there's deferred free work to be done) which would be
excessively costly, and there are also lock order considerations with
respect to how the lock would be handled at fork.

instead, just use an atomic list.
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/fork_impl.h1
1 files changed, 0 insertions, 1 deletions
diff --git a/src/internal/fork_impl.h b/src/internal/fork_impl.h
index 5892c13b..ae3a79e5 100644
--- a/src/internal/fork_impl.h
+++ b/src/internal/fork_impl.h
@@ -2,7 +2,6 @@
 
 extern hidden volatile int *const __at_quick_exit_lockptr;
 extern hidden volatile int *const __atexit_lockptr;
-extern hidden volatile int *const __dlerror_lockptr;
 extern hidden volatile int *const __gettext_lockptr;
 extern hidden volatile int *const __locale_lockptr;
 extern hidden volatile int *const __random_lockptr;