<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/thread, branch v1.2.4</title>
<subtitle>musl - an implementation of the standard library for Linux-based systems</subtitle>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/'/>
<entry>
<title>fix pthread_detach inadvertently acting as cancellation point in race case</title>
<updated>2023-02-11T18:00:22+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2023-02-11T14:54:12+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=c3cd04fa5fecd2c349aefde090c602554ee4fa24'/>
<id>c3cd04fa5fecd2c349aefde090c602554ee4fa24</id>
<content type='text'>
disabling cancellation around the pthread_join call seems to be the
safest and logically simplest fix. i believe it would also be possible
to just perform the unmap directly here after __tl_sync, removing the
dependency on pthread_join, but such an approach duplicately encodes a
lot more implementation assumptions.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
disabling cancellation around the pthread_join call seems to be the
safest and logically simplest fix. i believe it would also be possible
to just perform the unmap directly here after __tl_sync, removing the
dependency on pthread_join, but such an approach duplicately encodes a
lot more implementation assumptions.
</pre>
</div>
</content>
</entry>
<entry>
<title>use libc-internal malloc for pthread_atfork</title>
<updated>2022-12-17T21:00:19+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-12-17T21:00:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=9532ae1318201d66b235a618df16aac0b3386630'/>
<id>9532ae1318201d66b235a618df16aac0b3386630</id>
<content type='text'>
while no lock is held here making it a lock-order issue, replacement
malloc is likely to want to use pthread_atfork, possibly making the
call to malloc infinitely recursive.

even if not, there is no reason to prefer an application-provided
malloc here.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
while no lock is held here making it a lock-order issue, replacement
malloc is likely to want to use pthread_atfork, possibly making the
call to malloc infinitely recursive.

even if not, there is no reason to prefer an application-provided
malloc here.
</pre>
</div>
</content>
</entry>
<entry>
<title>semaphores: fix missed wakes from ABA bug in waiter count logic</title>
<updated>2022-12-13T23:39:44+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-12-13T23:39:44+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=159d1f6c02569091c7a48bdb2e2e824b844a1902'/>
<id>159d1f6c02569091c7a48bdb2e2e824b844a1902</id>
<content type='text'>
because the has-waiters state in the semaphore value futex word is
only representable when the value is zero (the special value -1
represents "0 with potential new waiters"), it's lost if intervening
operations make the semaphore value positive again. this creates an
ABA issue in sem_post, whereby the post uses a stale waiters count
rather than re-evaluating it, skipping the futex wake if the stale
count was zero.

the fix here is based on a proposal by Alexey Izbyshev, with minor
changes to eliminate costly new spurious wake syscalls.

the basic idea is to replace the special value -1 with a sticky
waiters bit (repurposing the sign bit) preserved under both wait and
post. any post that takes place with the waiters bit set will perform
a futex wake.

to be useful, the waiters bit needs to be removable, and to remove it
safely, we perform a broadcast wake instead of a normal single-task
wake whenever removing the bit. this lets any un-accounted-for waiters
wake and re-add the waiters bit if they still need it.

there are multiple possible choices for when to perform this
broadcast, but the optimal choice seems to be doing it whenever the
observed waiters count is less than two (semantically, this means
exactly one, but we might see a stale count of zero). in this case,
the expected number of threads to be woken is one, with exactly the
same cost as a non-broadcast wake.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
because the has-waiters state in the semaphore value futex word is
only representable when the value is zero (the special value -1
represents "0 with potential new waiters"), it's lost if intervening
operations make the semaphore value positive again. this creates an
ABA issue in sem_post, whereby the post uses a stale waiters count
rather than re-evaluating it, skipping the futex wake if the stale
count was zero.

the fix here is based on a proposal by Alexey Izbyshev, with minor
changes to eliminate costly new spurious wake syscalls.

the basic idea is to replace the special value -1 with a sticky
waiters bit (repurposing the sign bit) preserved under both wait and
post. any post that takes place with the waiters bit set will perform
a futex wake.

to be useful, the waiters bit needs to be removable, and to remove it
safely, we perform a broadcast wake instead of a normal single-task
wake whenever removing the bit. this lets any un-accounted-for waiters
wake and re-add the waiters bit if they still need it.

there are multiple possible choices for when to perform this
broadcast, but the optimal choice seems to be doing it whenever the
observed waiters count is less than two (semantically, this means
exactly one, but we might see a stale count of zero). in this case,
the expected number of threads to be woken is one, with exactly the
same cost as a non-broadcast wake.
</pre>
</div>
</content>
</entry>
<entry>
<title>pthread_atfork: fix return value on malloc failure</title>
<updated>2022-11-12T17:22:38+00:00</updated>
<author>
<name>Alexey Izbyshev</name>
<email>izbyshev@ispras.ru</email>
</author>
<published>2022-11-12T13:31:01+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=377218cb963aa20c6eb91781b0c79ad606631e6f'/>
<id>377218cb963aa20c6eb91781b0c79ad606631e6f</id>
<content type='text'>
POSIX requires pthread_atfork to report errors via its return value,
not via errno. The only specified error is ENOMEM.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
POSIX requires pthread_atfork to report errors via its return value,
not via errno. The only specified error is ENOMEM.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix async thread cancellation stack alignment</title>
<updated>2022-11-05T22:59:53+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-11-05T22:53:11+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=ad5dcd398b9509cf43672e3a7f02c4b18035998c'/>
<id>ad5dcd398b9509cf43672e3a7f02c4b18035998c</id>
<content type='text'>
if async cancellation is enabled and acted upon, the stack pointer is
not necessarily pointing to a __syscall_cp_asm stack frame. the
contents of the stack being wrong don't really matter, but if the
stack pointer is not suitably aligned, the procedure call ABI is
violated when calling back into C code via __cancel, and pthread_exit,
cancellation cleanup handlers, TSD destructors, etc. may malfunction
or crash.

for the async cancel case, just call __cancel directly like we did
prior to commit 102f6a01e249ce4495f1119ae6d963a2a4a53ce5. restore the
signal mask prior to doing this since the cancellation handler runs
with all signals blocked.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
if async cancellation is enabled and acted upon, the stack pointer is
not necessarily pointing to a __syscall_cp_asm stack frame. the
contents of the stack being wrong don't really matter, but if the
stack pointer is not suitably aligned, the procedure call ABI is
violated when calling back into C code via __cancel, and pthread_exit,
cancellation cleanup handlers, TSD destructors, etc. may malfunction
or crash.

for the async cancel case, just call __cancel directly like we did
prior to commit 102f6a01e249ce4495f1119ae6d963a2a4a53ce5. restore the
signal mask prior to doing this since the cancellation handler runs
with all signals blocked.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix missing synchronization of pthread TSD keys with MT-fork</title>
<updated>2022-10-19T18:01:32+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-10-08T01:36:25+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=cf76df0e1fe09b0d504ca650fdaa01df5bf9ab72'/>
<id>cf76df0e1fe09b0d504ca650fdaa01df5bf9ab72</id>
<content type='text'>
commit 167390f05564e0a4d3fcb4329377fd7743267560 seems to have
overlooked the presence of a lock here, probably because it was one of
the exceptions not using LOCK() but a rwlock.

as such, it can't be added to the generic table of locks to take, so
add an explicit atfork function for the pthread keys table. the order
it is called does not particularly matter since nothing else in libc
but pthread_exit interacts with keys.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 167390f05564e0a4d3fcb4329377fd7743267560 seems to have
overlooked the presence of a lock here, probably because it was one of
the exceptions not using LOCK() but a rwlock.

as such, it can't be added to the generic table of locks to take, so
add an explicit atfork function for the pthread keys table. the order
it is called does not particularly matter since nothing else in libc
but pthread_exit interacts with keys.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix potential unsynchronized access to killlock state at thread exit</title>
<updated>2022-10-19T18:01:32+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-10-05T15:07:52+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=d64148a8743ad9ed0594091d2ff141b1e9334d4b'/>
<id>d64148a8743ad9ed0594091d2ff141b1e9334d4b</id>
<content type='text'>
as reported by Alexey Izbyshev, when the second-to-last thread exits
causing a return to single-threaded (no locks needed) state, it
creates a situation where the last remaining thread may obtain the
killlock that's already held by the exiting thread. this means it may
erroneously use the tid of the exiting thread, and may corrupt the
lock state due to double-unlock.

commit 8d81ba8c0bc6fe31136cb15c9c82ef4c24965040, which (re)introduced
the switch back to single-threaded state, documents the intent that
the first lock after switching back should provide the necessary
synchronization. this is correct, but only works if the switch back is
made after there is no further need for synchronization with locks
(other than the thread list lock, which can't be bypassed) held by the
exiting thread.

in order to hit the bug, the remaining thread must first take a
different lock, causing it to perform an actual lock one last time,
consume the need_locks==-1 state, and transition to need_locks==0.
after that, the next attempt to lock the exiting thread's killlock
will bypass locking.

fix this by reordering the unlocking of killlock at thread exit time,
along with changes to the state protected by it, to occur earlier,
before the switch to single-threaded state. there are really no
constraints on where it's done, except that it occur after there is no
longer any possibility of application code executing in the exiting
thread, so do it as early as possible.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
as reported by Alexey Izbyshev, when the second-to-last thread exits
causing a return to single-threaded (no locks needed) state, it
creates a situation where the last remaining thread may obtain the
killlock that's already held by the exiting thread. this means it may
erroneously use the tid of the exiting thread, and may corrupt the
lock state due to double-unlock.

commit 8d81ba8c0bc6fe31136cb15c9c82ef4c24965040, which (re)introduced
the switch back to single-threaded state, documents the intent that
the first lock after switching back should provide the necessary
synchronization. this is correct, but only works if the switch back is
made after there is no further need for synchronization with locks
(other than the thread list lock, which can't be bypassed) held by the
exiting thread.

in order to hit the bug, the remaining thread must first take a
different lock, causing it to perform an actual lock one last time,
consume the need_locks==-1 state, and transition to need_locks==0.
after that, the next attempt to lock the exiting thread's killlock
will bypass locking.

fix this by reordering the unlocking of killlock at thread exit time,
along with changes to the state protected by it, to occur earlier,
before the switch to single-threaded state. there are really no
constraints on where it's done, except that it occur after there is no
longer any possibility of application code executing in the exiting
thread, so do it as early as possible.
</pre>
</div>
</content>
</entry>
<entry>
<title>use alt signal stack when present for implementation-internal signals</title>
<updated>2022-08-20T16:24:49+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-08-20T16:24:49+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=2e5fff43dd7fc808197744c67cca7908ac19bb4f'/>
<id>2e5fff43dd7fc808197744c67cca7908ac19bb4f</id>
<content type='text'>
a request for this behavior has been open for a long time. the
motivation is that application code, particularly under some language
runtimes designed around very-low-footprint coroutine type constructs,
may be operating with extremely small stack sizes unsuitable for
receiving signals, using a separate signal stack for any signals it
might handle.

progress on this was blocked at one point trying to determine whether
the implementation is actually entitled to clobber the alt stack, but
the phrasing "available to the implementation" in the POSIX spec for
sigaltstack seems to make it clear that the application cannot rely on
the contents of this memory to be preserved in the absence of signal
delivery (on the abstract machine, excluding implementation-internal
signals) and that we can therefore use it for delivery of signals that
"don't exist" on the abstract machine.

no change is made for SIGTIMER since it is always blocked when used,
and accepted via sigwaitinfo rather than execution of the signal
handler.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
a request for this behavior has been open for a long time. the
motivation is that application code, particularly under some language
runtimes designed around very-low-footprint coroutine type constructs,
may be operating with extremely small stack sizes unsuitable for
receiving signals, using a separate signal stack for any signals it
might handle.

progress on this was blocked at one point trying to determine whether
the implementation is actually entitled to clobber the alt stack, but
the phrasing "available to the implementation" in the POSIX spec for
sigaltstack seems to make it clear that the application cannot rely on
the contents of this memory to be preserved in the absence of signal
delivery (on the abstract machine, excluding implementation-internal
signals) and that we can therefore use it for delivery of signals that
"don't exist" on the abstract machine.

no change is made for SIGTIMER since it is always blocked when used,
and accepted via sigwaitinfo rather than execution of the signal
handler.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix error checking in pthread_getname_np</title>
<updated>2021-08-06T15:26:15+00:00</updated>
<author>
<name>Érico Nogueira</name>
<email>ericonr@disroot.org</email>
</author>
<published>2021-07-10T03:24:59+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=3eed6a6f0a400763313bc5dca6e3b22a75166dbe'/>
<id>3eed6a6f0a400763313bc5dca6e3b22a75166dbe</id>
<content type='text'>
len is unsigned and can never be smaller than 0. though unlikely, an
error in read() would have lead to an out of bounds write to name.

Reported-by: Michael Forney &lt;mforney@mforney.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
len is unsigned and can never be smaller than 0. though unlikely, an
error in read() would have lead to an out of bounds write to name.

Reported-by: Michael Forney &lt;mforney@mforney.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>add pthread_getname_np function</title>
<updated>2021-04-20T19:34:30+00:00</updated>
<author>
<name>Érico Rolim</name>
<email>ericonr@disroot.org</email>
</author>
<published>2021-04-20T19:15:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=bd3b9c4ca5e93f10f7fd891b8c07cc0c5dfd198f'/>
<id>bd3b9c4ca5e93f10f7fd891b8c07cc0c5dfd198f</id>
<content type='text'>
based on the pthread_setname_np implementation
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
based on the pthread_setname_np implementation
</pre>
</div>
</content>
</entry>
</feed>
