Init fork handler after __libc_init_malloc.
pthread_atfork may call malloc() during its once-init. This causes
problems with allocators (GWP-ASan) that require explicit initialisation
before calls to malloc().
Bug: 135634846
Test: atest bionic
Change-Id: I1810a00465db99d5aa34fa6f74dea5908a628d3a
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 1f099cf..b6a9ed2 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -101,13 +101,15 @@
__libc_add_main_thread();
- // Register atfork handlers to take and release the arc4random lock.
- pthread_atfork(arc4random_fork_handler, _thread_arc4_unlock, _thread_arc4_unlock);
-
__system_properties_init(); // Requires 'environ'.
__libc_init_fdsan(); // Requires system properties (for debug.fdsan).
}
+void __libc_init_fork_handler() {
+ // Register atfork handlers to take and release the arc4random lock.
+ pthread_atfork(arc4random_fork_handler, _thread_arc4_unlock, _thread_arc4_unlock);
+}
+
__noreturn static void __early_abort(int line) {
// We can't write to stdout or stderr because we're aborting before we've checked that
// it's safe for us to use those file descriptors. We probably can't strace either, so
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 73f5817..0c2e78a 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -56,4 +56,8 @@
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(char** envp);
+// The fork handler must be initialised after __libc_init_malloc, as
+// pthread_atfork may call malloc() during its once-init.
+__LIBC_HIDDEN__ void __libc_init_fork_handler();
+
#endif
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index d6d5552..ca94652 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -99,6 +99,8 @@
// Hooks for various libraries to let them know that we're starting up.
__libc_globals.mutate(__libc_init_malloc);
+ __libc_init_fork_handler();
+
#if __has_feature(hwaddress_sanitizer)
// Notify the HWASan runtime library whenever a library is loaded or unloaded
// so that it can update its shadow memory.
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 28c0b0c..5c1d27e 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -181,6 +181,7 @@
layout_static_tls(args);
__libc_init_main_thread_final();
__libc_init_common();
+ __libc_init_fork_handler();
call_ifunc_resolvers();
apply_gnu_relro();