summaryrefslogtreecommitdiff
path: root/src/thread/pthread_create.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2020-07-06 17:56:19 -0400
committerRich Felker <dalias@aerifal.cx>2020-07-06 17:56:19 -0400
commit7cc9496a18c3fa665c286b8be41d790c795e0171 (patch)
tree8d2d2e901495af4692d3b5cbd50a71e7d679f8dd /src/thread/pthread_create.c
parent0a005f499cf39822166dd4db3d2d31f0639f1b1b (diff)
downloadmusl-7cc9496a18c3fa665c286b8be41d790c795e0171.tar.gz
make thread killlock async-signal-safe for pthread_kill
pthread_kill is required to be AS-safe. that requirement can't be met if the target thread's killlock can be taken in contexts where application-installed signal handlers can run. block signals around use of this lock in all pthread_* functions which target a tid, and reorder blocking/unblocking of signals in pthread_exit so that they're blocked whenever the killlock is held.
Diffstat (limited to 'src/thread/pthread_create.c')
-rw-r--r--src/thread/pthread_create.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index 6bdfb44f..10f1b7d8 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -72,12 +72,13 @@ _Noreturn void __pthread_exit(void *result)
/* Access to target the exiting thread with syscalls that use
* its kernel tid is controlled by killlock. For detached threads,
* any use past this point would have undefined behavior, but for
- * joinable threads it's a valid usage that must be handled. */
+ * joinable threads it's a valid usage that must be handled.
+ * Signals must be blocked since pthread_kill must be AS-safe. */
+ __block_app_sigs(&set);
LOCK(self->killlock);
- /* The thread list lock must be AS-safe, and thus requires
- * application signals to be blocked before it can be taken. */
- __block_app_sigs(&set);
+ /* The thread list lock must be AS-safe, and thus depends on
+ * application signals being blocked above. */
__tl_lock();
/* If this is the only thread in the list, don't proceed with
@@ -85,8 +86,8 @@ _Noreturn void __pthread_exit(void *result)
* signal state to prepare for exit to call atexit handlers. */
if (self->next == self) {
__tl_unlock();
- __restore_sigs(&set);
UNLOCK(self->killlock);
+ __restore_sigs(&set);
exit(0);
}