diff options
| author | Samuel Holland <samuel@sholland.org> | 2019-06-30 22:44:28 -0500 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2019-07-01 10:10:52 -0400 | 
| commit | 84ebec6ceea997568c1711e7d810ad6bb3a96346 (patch) | |
| tree | 205112963e85f6d7e7db5a2d929da6e8131b8ff0 /src | |
| parent | 3d178a7e2b75066593fbd5705742c5808395d90d (diff) | |
| download | musl-84ebec6ceea997568c1711e7d810ad6bb3a96346.tar.gz | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/process/fork.c | 1 | 
1 files changed, 1 insertions, 0 deletions
| diff --git a/src/process/fork.c b/src/process/fork.c index 11286ef4..fb42478a 100644 --- a/src/process/fork.c +++ b/src/process/fork.c @@ -28,6 +28,7 @@ pid_t fork(void)  		self->robust_list.off = 0;  		self->robust_list.pending = 0;  		self->next = self->prev = self; +		__thread_list_lock = 0;  		libc.threads_minus_1 = 0;  	}  	__restore_sigs(&set); | 
