external/musl/libc
Revision | 84ebec6ceea997568c1711e7d810ad6bb3a96346 (tree) |
---|---|
Time | 2019-07-01 23:10:52 |
Author | Samuel Holland <samuel@shol...> |
Commiter | Rich Felker |
fix deadlock in synccall after threaded fork
synccall may be called by AS-safe functions such as setuid/setgid after
fork. although fork() resets libc.threads_minus_one, causing synccall to
take the single-threaded path, synccall still takes the thread list
lock. This lock may be held by another thread if for example fork()
races with pthread_create(). After fork(), the value of the lock is
meaningless, so clear it.
maintainer's note: commit 8f11e6127fe93093f81a52b15bb1537edc3fc8af and
e4235d70672d9751d7718ddc2b52d0b426430768 introduced this regression.
the state protected by this lock is the linked list, which is entirely
replaced in the child path of fork (next=prev=self), so resetting it
is semantically sound.
@@ -28,6 +28,7 @@ pid_t fork(void) | ||
28 | 28 | self->robust_list.off = 0; |
29 | 29 | self->robust_list.pending = 0; |
30 | 30 | self->next = self->prev = self; |
31 | + __thread_list_lock = 0; | |
31 | 32 | libc.threads_minus_1 = 0; |
32 | 33 | } |
33 | 34 | __restore_sigs(&set); |