<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/process, 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>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>
<entry>
<title>fail posix_spawn file_actions operations with negative fds</title>
<updated>2021-01-30T21:09:22+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2021-01-30T21:09:22+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=dd5b6384712fb554bb6e291f2bbcdc9ec2f66554'/>
<id>dd5b6384712fb554bb6e291f2bbcdc9ec2f66554</id>
<content type='text'>
these functions are specified to fail with EBADF on negative fd
arguments. apart from close, they are also specified to fail if the
value exceeds OPEN_MAX, but as written it is not clear that this
imposes any requirement when OPEN_MAX is not defined, and it's
undesirable to impose a dynamic limit (via setrlimit) here since the
limit at the time of posix_spawn may be different from the limit at
the time of setting up the file actions. this may require revisiting
later.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
these functions are specified to fail with EBADF on negative fd
arguments. apart from close, they are also specified to fail if the
value exceeds OPEN_MAX, but as written it is not clear that this
imposes any requirement when OPEN_MAX is not defined, and it's
undesirable to impose a dynamic limit (via setrlimit) here since the
limit at the time of posix_spawn may be different from the limit at
the time of setting up the file actions. this may require revisiting
later.
</pre>
</div>
</content>
</entry>
<entry>
<title>lift child restrictions after multi-threaded fork</title>
<updated>2020-11-11T20:55:30+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2020-11-11T18:37:33+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=167390f05564e0a4d3fcb4329377fd7743267560'/>
<id>167390f05564e0a4d3fcb4329377fd7743267560</id>
<content type='text'>
as the outcome of Austin Group tracker issue #62, future editions of
POSIX have dropped the requirement that fork be AS-safe. this allows
but does not require implementations to synchronize fork with internal
locks and give forked children of multithreaded parents a partly or
fully unrestricted execution environment where they can continue to
use the standard library (per POSIX, they can only portably use
AS-safe functions).

up until recently, taking this allowance did not seem desirable.
however, commit 8ed2bd8bfcb4ea6448afb55a941f4b5b2b0398c0 exposed the
extent to which applications and libraries are depending on the
ability to use malloc and other non-AS-safe interfaces in MT-forked
children, by converting latent very-low-probability catastrophic state
corruption into predictable deadlock. dealing with the fallout has
been a huge burden for users/distros.

while it looks like most of the non-portable usage in applications
could be fixed given sufficient effort, at least some of it seems to
occur in language runtimes which are exposing the ability to run
unrestricted code in the child as part of the contract with the
programmer. any attempt at fixing such contracts is not just a
technical problem but a social one, and is probably not tractable.

this patch extends the fork function to take locks for all libc
singletons in the parent, and release or reset those locks in the
child, so that when the underlying fork operation takes place, the
state protected by these locks is consistent and ready for the child
to use. locking is skipped in the case where the parent is
single-threaded so as not to interfere with legacy AS-safety property
of fork in single-threaded programs. lock order is mostly arbitrary,
but the malloc locks (including bump allocator in case it's used) must
be taken after the locks on any subsystems that might use malloc, and
non-AS-safe locks cannot be taken while the thread list lock is held,
imposing a requirement that it be taken last.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
as the outcome of Austin Group tracker issue #62, future editions of
POSIX have dropped the requirement that fork be AS-safe. this allows
but does not require implementations to synchronize fork with internal
locks and give forked children of multithreaded parents a partly or
fully unrestricted execution environment where they can continue to
use the standard library (per POSIX, they can only portably use
AS-safe functions).

up until recently, taking this allowance did not seem desirable.
however, commit 8ed2bd8bfcb4ea6448afb55a941f4b5b2b0398c0 exposed the
extent to which applications and libraries are depending on the
ability to use malloc and other non-AS-safe interfaces in MT-forked
children, by converting latent very-low-probability catastrophic state
corruption into predictable deadlock. dealing with the fallout has
been a huge burden for users/distros.

while it looks like most of the non-portable usage in applications
could be fixed given sufficient effort, at least some of it seems to
occur in language runtimes which are exposing the ability to run
unrestricted code in the child as part of the contract with the
programmer. any attempt at fixing such contracts is not just a
technical problem but a social one, and is probably not tractable.

this patch extends the fork function to take locks for all libc
singletons in the parent, and release or reset those locks in the
child, so that when the underlying fork operation takes place, the
state protected by these locks is consistent and ready for the child
to use. locking is skipped in the case where the parent is
single-threaded so as not to interfere with legacy AS-safety property
of fork in single-threaded programs. lock order is mostly arbitrary,
but the malloc locks (including bump allocator in case it's used) must
be taken after the locks on any subsystems that might use malloc, and
non-AS-safe locks cannot be taken while the thread list lock is held,
imposing a requirement that it be taken last.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix reintroduction of errno clobbering by atfork handlers</title>
<updated>2020-10-26T22:12:25+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2020-10-26T22:06:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=3437e478ba932edbab18a90638c20be1f0141156'/>
<id>3437e478ba932edbab18a90638c20be1f0141156</id>
<content type='text'>
commit bd153422f28634bb6e53f13f80beb8289d405267 reintroduced the bug
fixed in c21051e90cd27a0b26be0ac66950b7396a156ba1 by refactoring the
__syscall_ret into _Fork where it once again runs before the atfork
handlers are called. since _Fork is a public interface that sets
errno, this can't be fixed the way it was fixed last time without
making new internal interfaces. instead, just save errno, and restore
it only on error to ensure that a value of 0 is never restored.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit bd153422f28634bb6e53f13f80beb8289d405267 reintroduced the bug
fixed in c21051e90cd27a0b26be0ac66950b7396a156ba1 by refactoring the
__syscall_ret into _Fork where it once again runs before the atfork
handlers are called. since _Fork is a public interface that sets
errno, this can't be fixed the way it was fixed last time without
making new internal interfaces. instead, just save errno, and restore
it only on error to ensure that a value of 0 is never restored.
</pre>
</div>
</content>
</entry>
<entry>
<title>move aio implementation details to a proper internal header</title>
<updated>2020-10-15T00:27:12+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2020-09-28T22:47:13+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=557673603bb553e90106e7d14da6447a5ff82164'/>
<id>557673603bb553e90106e7d14da6447a5ff82164</id>
<content type='text'>
also fix the lack of declaration (and thus hidden visibility) in
__stdio_close's use of __aio_close.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
also fix the lack of declaration (and thus hidden visibility) in
__stdio_close's use of __aio_close.
</pre>
</div>
</content>
</entry>
</feed>
