toolchain/gcc: switch to version 11 by default
[openwrt/staging/chunkeey.git] / toolchain / musl / patches / 500-0001-reorder-thread-list-unlink-in-pthread_exit-after-all.patch
1 From 4d5aa20a94a2d3fae3e69289dc23ecafbd0c16c4 Mon Sep 17 00:00:00 2001
2 From: Rich Felker <dalias@aerifal.cx>
3 Date: Fri, 22 May 2020 17:35:14 -0400
4 Subject: [PATCH 1/4] reorder thread list unlink in pthread_exit after all
5 locks
6
7 since the backend for LOCK() skips locking if single-threaded, it's
8 unsafe to make the process appear single-threaded before the last use
9 of lock.
10
11 this fixes potential unsynchronized access to a linked list via
12 __dl_thread_cleanup.
13 ---
14 src/thread/pthread_create.c | 19 +++++++++++--------
15 1 file changed, 11 insertions(+), 8 deletions(-)
16
17 --- a/src/thread/pthread_create.c
18 +++ b/src/thread/pthread_create.c
19 @@ -90,14 +90,7 @@ _Noreturn void __pthread_exit(void *resu
20 exit(0);
21 }
22
23 - /* At this point we are committed to thread termination. Unlink
24 - * the thread from the list. This change will not be visible
25 - * until the lock is released, which only happens after SYS_exit
26 - * has been called, via the exit futex address pointing at the lock. */
27 - libc.threads_minus_1--;
28 - self->next->prev = self->prev;
29 - self->prev->next = self->next;
30 - self->prev = self->next = self;
31 + /* At this point we are committed to thread termination. */
32
33 /* Process robust list in userspace to handle non-pshared mutexes
34 * and the detached thread case where the robust list head will
35 @@ -121,6 +114,16 @@ _Noreturn void __pthread_exit(void *resu
36 __do_orphaned_stdio_locks();
37 __dl_thread_cleanup();
38
39 + /* Last, unlink thread from the list. This change will not be visible
40 + * until the lock is released, which only happens after SYS_exit
41 + * has been called, via the exit futex address pointing at the lock.
42 + * This needs to happen after any possible calls to LOCK() that might
43 + * skip locking if libc.threads_minus_1 is zero. */
44 + libc.threads_minus_1--;
45 + self->next->prev = self->prev;
46 + self->prev->next = self->next;
47 + self->prev = self->next = self;
48 +
49 /* This atomic potentially competes with a concurrent pthread_detach
50 * call; the loser is responsible for freeing thread resources. */
51 int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);