[PATCH] posix: Avoid allocation while holding atfork_lock [BZ 34321]

H.J. Lu hjl.tools@gmail.com
Mon Jun 29 21:55:42 GMT 2026


On Mon, Jun 29, 2026 at 7:14 PM Adhemerval Zanella Netto
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 26/06/26 19:59, H.J. Lu wrote:
> > On Sat, Jun 27, 2026 at 1:31 AM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> >>
> >> __register_atfork inserted the new handler into a dynamic array while
> >> holding atfork_lock, and growing that array calls the public/iterposable
> >> malloc.  An allocator replacement whose own lock is also taken from a
> >> registered pthread_atfork prepare handler can therefore deadlock:
> >>
> >>   Thread A: fork                          Thread B: __register_atfork
> >>   -------------------------------------   -----------------------------------
> >>   :139 unlock(atfork_lock)
> >>   :141 prepare() -> lock(L)   [holds L]
> >>                                           :39  lock(atfork_lock)  [holds atfork]
> >>                                           :44  emplace -> malloc -> lock(L)
> >>                                                BLOCKS on L (held by A)
> >>   :144 lock(atfork_lock)
> >>        BLOCKS on atfork (held by B)
> >>   => DEADLOCK (A: holds L, waits atfork; B: holds atfork, waits L)
> >>
> >> Replace the dynamic array with a doubly linked list (include/list.h).
> >> A new node is allocated outside atfork_lock and only linked in while the
> >> lock is held.  __unregister_atfork moves nodes to a free pool instead of
> >> freeing them, and __register_atfork reuses a pooled node when one is
> >> available, so neither path allocates or frees under atfork_lock in the
> >> steady state; malloc runs only to grow the pool, always outside the lock.
> >> This preserves the current allocation guarantee of the dynarray.
> >>
> >> Checked on x86_64-linux-gnu and aarch64-linux-gnu.
> >
> > Is it possible to create a run-time test with an alternate malloc via
> > LD_PRELOAD on systems where alternate malloc is available
> > similar to
> >
> > https://gitlab.com/x86-glibc/glibc/-/commits/users/hjl/test/malloc
> I think for checking this issue being a LD_PRELOAD or malloc implemented
> in the binary itself does not really matter. The mechanism glibc will used
> to trigger is the same, and being on the binary makes it simpler.

Without LD_PRELOAD, we can't be sure that the issue is really fixed.
We may have fixed a slighly different issue.

-- 
H.J.


More information about the Libc-alpha mailing list