Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260924021222.GC23438@brightrain.aerifal.cx>
Date: Wed, 23 Sep 2026 22:12:22 -0400
From: Rich Felker <dalias@...c.org>
To: Trevor Gross <tg@...vorgross.com>
Cc: musl@...ts.openwall.com, linux-man@...r.kernel.org,
	libc-alpha@...rceware.org
Subject: Re: Re: async-signal-safety of chroot

On Wed, Sep 23, 2026 at 07:34:35PM -0500, Trevor Gross wrote:
> On Tue Sep 22, 2026 at 8:34 PM CDT, Rich Felker wrote:
> >
> > Also, both glibc and musl relax the restriction on only calling
> > AS-safe functions in the child after a multi-threaded parent forks. In
> > glibc this is sort of a best-effort thing, but in musl we went through
> > a detailed process of ensuring that everything is made consistent for
> > the child. The only thing that might not be consistent is dynamic
> > linker state, which might make it impossible to dlopen in the child,
> > but this is treated as a reportable error condition not a crash or
> > deadlock or anything.
> >
> > The changes to lift the restrictions on the child happened in commit
> > 167390f05564e0a4d3fcb4329377fd7743267560
> 
> A followup question: the usual wisdom has been that `fork` must always
> be followed by an `exec`, and not doing so is somewhere between
> error-prone and completely unsound.

I would not say that is "usual wisdom" at all. Traditional unix
practice was very much to take maximal advantage of fork. Lots of
daemons run connections/sessions this way, shells implement subshells
this way, etc.

I would say, however, that it's good practice not to fork except to
exec, and to avoid that too (use posix_spawn instead) when possible.
There are lots of pitfalls with keeping around a forked child, ranging
from leaking potentially sensitive data you didn't intent to copy from
the parent -- especially if dropping privileges in the child -- to
logic bugs around sole ownership of a resource potentially becoming
shared/multiple ownership. Plus there are the portability issues if
anything in the parent is using threads, or if you want to port to
systems where fork is slow, poorly emulated, or unavailable (Windows,
MMU-less microcontrollers, etc.)

> Based per the commit it sounds like
> there are no more deadlocks, and without the POSIX AS-safe requirement,
> the soundness question goes away. Does this mean that it is now
> considered correct and reasonable code to `fork` without `exec` for the
> purpose of e.g. invoking a function in a separate process?

This works on musl and maybe mostly on glibc, but unless you know the
parent is single-threaded, it's not portable. If you look back at the
reason we made it work, it's because one or more interpreted languages
(sorry I don't remember which one(s) at the moment) *wrongly assumed
it works* and built their own language constructs (exposed to
applications written in those languages) around the assumption that it
works.

> Similar to
> what can be done with `clone`.

Generally clone is far more dangerous than fork in this regard. There
is no formal spec for how it behaves, and you are likely stuck with
the same or tighter AS-safety restrictions than fork would have.

musl makes clone roughly as safe as fork (see commit fa4a8abd06a4),
and disallows flags that are not compatible with executing any part of
libc in the child, but afaik glibc still has an anything-goes
approach.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.