[Bug libc/34321] New: __register_atfork allocates while holding atfork_lock

"adhemerval.zanella at linaro dot org via Glibc-bugs" <[email protected]> Fri, 26 Jun 2026 12:30:09 +0000
Newsgroups gmane.comp.lib.glibc.bugs
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=34321

            Bug ID: 34321
           Summary: __register_atfork allocates while holding atfork_lock
           Product: glibc
           Version: 2.29
            Status: NEW
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: adhemerval.zanella at linaro dot org
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

The pthread_atfork registration (__register_atfork) inserts the new handler
into a dynamic array while holding the internal atfork_lock, and growing that
array calls the public/interposable malloc. In a process that replaces malloc
(tcmalloc, jemalloc, or any LD_PRELOAD allocator) and whose allocator also
registers a pthread_atfork prepare handler that takes the allocator's own lock,
this creates an ABBA lock-ordering 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)


A possible fix it to never allocate while holding atfork_lock, where the
handler storage is reverted back from a dynamic array to a doubly linked list.
I do not think we need to restore the lock-free version.

-- 
You are receiving this mail because:
You are on the CC list for the bug.