<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/process, branch v1.2.5</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>posix_spawn: fix child spinning on write to a broken pipe</title>
<updated>2024-02-29T15:07:03+00:00</updated>
<author>
<name>Alexey Izbyshev</name>
<email>izbyshev@ispras.ru</email>
</author>
<published>2024-02-29T11:13:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=d3a61059c04bd82329707324fac0d48e191edbf4'/>
<id>d3a61059c04bd82329707324fac0d48e191edbf4</id>
<content type='text'>
A child process created by posix_spawn reports errors to its parent via
a pipe, retrying infinitely on any write error to prevent falsely
reporting success. If the (original) parent dies before write is
attempted, there is nobody to report to, but the child will remain
stuck in the write loop forever if SIGPIPE is blocked or ignored.
Fix this by not retrying write if it fails with EPIPE.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A child process created by posix_spawn reports errors to its parent via
a pipe, retrying infinitely on any write error to prevent falsely
reporting success. If the (original) parent dies before write is
attempted, there is nobody to report to, but the child will remain
stuck in the write loop forever if SIGPIPE is blocked or ignored.
Fix this by not retrying write if it fails with EPIPE.
</pre>
</div>
</content>
</entry>
<entry>
<title>add framework to support archs without a native wait4 syscall</title>
<updated>2024-02-22T23:50:34+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2024-02-22T23:50:34+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=19563e1850808af216b1b84263bb7e83cccce506'/>
<id>19563e1850808af216b1b84263bb7e83cccce506</id>
<content type='text'>
this commit should make no codegen change for existing archs, but is a
prerequisite for new archs including riscv32. the wait4 emulation
backend provides both cancellable and non-cancellable variants because
waitpid is required to be a cancellation point, but all of our other
uses are not, and most of them cannot be.

based on patch by Stefan O'Rear.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this commit should make no codegen change for existing archs, but is a
prerequisite for new archs including riscv32. the wait4 emulation
backend provides both cancellable and non-cancellable variants because
waitpid is required to be a cancellation point, but all of our other
uses are not, and most of them cannot be.

based on patch by Stefan O'Rear.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix public clone function to be safe and usable by applications</title>
<updated>2023-06-01T20:15:38+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2023-05-31T16:04:06+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=fa4a8abd06a401822cc8ba4e352a219544c0118d'/>
<id>fa4a8abd06a401822cc8ba4e352a219544c0118d</id>
<content type='text'>
the clone() function has been effectively unusable since it was added,
due to producing a child process with inconsistent state. in
particular, the child process's thread structure still contains the
tid, thread list pointers, thread count, and robust list for the
parent. this will cause malfunction in interfaces that attempt to use
the tid or thread list, some of which are specified to be
async-signal-safe.

this patch attempts to make clone() consistent in a _Fork-like sense.
as in _Fork, when the parent process is multi-threaded, the child
process inherits an async-signal context where it cannot call
AS-unsafe functions, but its context is now intended to be safe for
calling AS-safe functions. making clone fork-like would also be a
future option, if it turns out that this is what makes sense to
applications, but it's not done at this time because the changes would
be more invasive.

in the case where the CLONE_VM flag is used, clone is only vfork-like,
not _Fork-like. in particular, the child will see itself as having the
parent's tid, and cannot safely call any libc functions but one of the
exec family or _exit.

handling of flags and variadic arguments is also changed so that
arguments are only consumed with flags that indicate their presence,
and so that flags which produce an inconsistent state are disallowed
(reported as EINVAL). in particular, all libc functions carry a
contract that they are only callable with ABI requirements met, which
includes having a valid thread pointer to a thread structure that's
unique within the process, and whose contents are opaque and only able
to be setup internally by the implementation. the only way for an
application to use flags that violate these requirements without
executing any libc code is to perform the syscall from
application-provided asm.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the clone() function has been effectively unusable since it was added,
due to producing a child process with inconsistent state. in
particular, the child process's thread structure still contains the
tid, thread list pointers, thread count, and robust list for the
parent. this will cause malfunction in interfaces that attempt to use
the tid or thread list, some of which are specified to be
async-signal-safe.

this patch attempts to make clone() consistent in a _Fork-like sense.
as in _Fork, when the parent process is multi-threaded, the child
process inherits an async-signal context where it cannot call
AS-unsafe functions, but its context is now intended to be safe for
calling AS-safe functions. making clone fork-like would also be a
future option, if it turns out that this is what makes sense to
applications, but it's not done at this time because the changes would
be more invasive.

in the case where the CLONE_VM flag is used, clone is only vfork-like,
not _Fork-like. in particular, the child will see itself as having the
parent's tid, and cannot safely call any libc functions but one of the
exec family or _exit.

handling of flags and variadic arguments is also changed so that
arguments are only consumed with flags that indicate their presence,
and so that flags which produce an inconsistent state are disallowed
(reported as EINVAL). in particular, all libc functions carry a
contract that they are only callable with ABI requirements met, which
includes having a valid thread pointer to a thread structure that's
unique within the process, and whose contents are opaque and only able
to be setup internally by the implementation. the only way for an
application to use flags that violate these requirements without
executing any libc code is to perform the syscall from
application-provided asm.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix broken thread list unlocking after fork</title>
<updated>2023-06-01T20:15:37+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2023-06-01T20:09:32+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=0c277ff156749628c678257f878d3a6edb5868de'/>
<id>0c277ff156749628c678257f878d3a6edb5868de</id>
<content type='text'>
apparently Linux clears the registered exit futex address on fork.
this means that, if after forking the child process becomes
multithreaded and the original thread exits, the thread list will
never be unlocked, and future attempts to use the thread list will
deadlock.

re-register the exit futex address after _Fork in the child to ensure
that it's preserved.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
apparently Linux clears the registered exit futex address on fork.
this means that, if after forking the child process becomes
multithreaded and the original thread exits, the thread list will
never be unlocked, and future attempts to use the thread list will
deadlock.

re-register the exit futex address after _Fork in the child to ensure
that it's preserved.
</pre>
</div>
</content>
</entry>
<entry>
<title>riscv64: add vfork</title>
<updated>2023-02-09T17:33:35+00:00</updated>
<author>
<name>Pedro Falcato</name>
<email>pedro.falcato@gmail.com</email>
</author>
<published>2023-02-09T16:34:12+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=5763f003a53ddaa63655058f19d9fe662751592d'/>
<id>5763f003a53ddaa63655058f19d9fe662751592d</id>
<content type='text'>
Implement vfork() using clone(CLONE_VM | CLONE_VFORK | ...).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Implement vfork() using clone(CLONE_VM | CLONE_VFORK | ...).
</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 deadlock between multithreaded fork and aio</title>
<updated>2022-10-19T18:01:32+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2022-10-07T00:53:01+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=aebd6a36449e91c06763a40121d558b6cea90d50'/>
<id>aebd6a36449e91c06763a40121d558b6cea90d50</id>
<content type='text'>
as reported by Alexey Izbyshev, there is a lock order inversion
deadlock between the malloc lock and aio maplock at MT-fork time:
_Fork attempts to take the aio maplock while fork already has the
malloc lock, but a concurrent aio operation holding the maplock may
attempt to allocate memory.

move the __aio_atfork calls in the parent from _Fork to fork, and
reorder the lock before most other locks, since nothing else depends
on aio(*). this leaves us with the possibility that the child will not
be able to obtain the read lock, if _Fork is used directly and happens
concurrent with an aio operation. however, in that case, the child
context is an async signal context that cannot call any further aio
functions, so all we need is to ensure that close does not attempt to
perform any aio cancellation. this can be achieved just by nulling out
the map pointer.

(*) even if other functions call close, they will only need a read
lock, not a write lock, and read locks being recursive ensures they
can obtain it. moreover, the number of read references held is bounded
by something like twice the number of live threads, meaning that the
read lock count cannot saturate.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
as reported by Alexey Izbyshev, there is a lock order inversion
deadlock between the malloc lock and aio maplock at MT-fork time:
_Fork attempts to take the aio maplock while fork already has the
malloc lock, but a concurrent aio operation holding the maplock may
attempt to allocate memory.

move the __aio_atfork calls in the parent from _Fork to fork, and
reorder the lock before most other locks, since nothing else depends
on aio(*). this leaves us with the possibility that the child will not
be able to obtain the read lock, if _Fork is used directly and happens
concurrent with an aio operation. however, in that case, the child
context is an async signal context that cannot call any further aio
functions, so all we need is to ensure that close does not attempt to
perform any aio cancellation. this can be achieved just by nulling out
the map pointer.

(*) even if other functions call close, they will only need a read
lock, not a write lock, and read locks being recursive ensures they
can obtain it. moreover, the number of read references held is bounded
by something like twice the number of live threads, meaning that the
read lock count cannot saturate.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix potential deadlock in dlerror buffer handling 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-05T14:41:30+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf'/>
<id>36b72cd6fdfed2cac6b6ff1ed58a96d8265785cf</id>
<content type='text'>
ever since commit 8f11e6127fe93093f81a52b15bb1537edc3fc8af introduced
the thread list lock, this has been wrong. initially, it was wrong via
calling free from the context with the thread list lock held. commit
aa5a9d15e09851f7b4a1668e9dbde0f6234abada deferred the unsafe free but
added a lock, which was also unsafe. in particular, it could deadlock
if code holding freebuf_queue_lock was interrupted by a signal handler
that takes the thread list lock.

commit 4d5aa20a94a2d3fae3e69289dc23ecafbd0c16c4 observed that there
was a lock here but failed to notice that it's invalid.

there is no easy solution to this problem with locks; any attempt at
solving it while still using locks would require the lock to be an
AS-safe one (blocking signals on each access to the dlerror buffer
list to check if there's deferred free work to be done) which would be
excessively costly, and there are also lock order considerations with
respect to how the lock would be handled at fork.

instead, just use an atomic list.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ever since commit 8f11e6127fe93093f81a52b15bb1537edc3fc8af introduced
the thread list lock, this has been wrong. initially, it was wrong via
calling free from the context with the thread list lock held. commit
aa5a9d15e09851f7b4a1668e9dbde0f6234abada deferred the unsafe free but
added a lock, which was also unsafe. in particular, it could deadlock
if code holding freebuf_queue_lock was interrupted by a signal handler
that takes the thread list lock.

commit 4d5aa20a94a2d3fae3e69289dc23ecafbd0c16c4 observed that there
was a lock here but failed to notice that it's invalid.

there is no easy solution to this problem with locks; any attempt at
solving it while still using locks would require the lock to be an
AS-safe one (blocking signals on each access to the dlerror buffer
list to check if there's deferred free work to be done) which would be
excessively costly, and there are also lock order considerations with
respect to how the lock would be handled at fork.

instead, just use an atomic list.
</pre>
</div>
</content>
</entry>
<entry>
<title>aarch64: add vfork</title>
<updated>2022-08-01T17:37:39+00:00</updated>
<author>
<name>Szabolcs Nagy</name>
<email>nsz@port70.net</email>
</author>
<published>2022-07-16T13:55:51+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=4f48da008d1fb3ccab2ad76523c104aa3fa8d8b6'/>
<id>4f48da008d1fb3ccab2ad76523c104aa3fa8d8b6</id>
<content type='text'>
The generic vfork implementation uses clone(SIGCHLD) which has fork
semantics.

Implement vfork as clone(SIGCHLD|CLONE_VM|CLONE_VFORK, 0) instead which
has vfork semantics. (stack == 0 means sp is unchanged in the child.)

Some users rely on vfork semantics when memory overcommit is disabled
or when the vfork child runs code that synchronizes with the parent
process (non-conforming).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The generic vfork implementation uses clone(SIGCHLD) which has fork
semantics.

Implement vfork as clone(SIGCHLD|CLONE_VM|CLONE_VFORK, 0) instead which
has vfork semantics. (stack == 0 means sp is unchanged in the child.)

Some users rely on vfork semantics when memory overcommit is disabled
or when the vfork child runs code that synchronizes with the parent
process (non-conforming).
</pre>
</div>
</content>
</entry>
<entry>
<title>use internal malloc for posix_spawn file actions objects</title>
<updated>2021-03-15T14:21:29+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2021-03-15T14:21:29+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=8ef9d46f4d0ff4f0073da6bee7ed0cb5f9035ead'/>
<id>8ef9d46f4d0ff4f0073da6bee7ed0cb5f9035ead</id>
<content type='text'>
this makes it possible to perform actions on file actions objects with
a libc-internal lock held without creating lock order relationships
that are silently imposed on an application-provided malloc.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this makes it possible to perform actions on file actions objects with
a libc-internal lock held without creating lock order relationships
that are silently imposed on an application-provided malloc.
</pre>
</div>
</content>
</entry>
</feed>
