From 573721bf0c302c453620a883a4adf37935646d4a Mon Sep 17 00:00:00 2001 From: PiJoules <6019989+PiJoules@users.noreply.github.com> Date: Tue, 6 May 2025 10:03:38 -0700 Subject: [PATCH] [sanitizer][Fuchsia] Add callback at end of __sanitizer_startup_hook (#131886) Sanitizers using this hook on Fuchsia can define this function to do any extra stuff at the end of the startup hook. For now this is only used by HWASan which needs to explicitly be initialized before libc extensions are intitialized. --- compiler-rt/lib/asan/asan_fuchsia.cpp | 5 +++++ compiler-rt/lib/hwasan/hwasan_fuchsia.cpp | 9 +++++++++ compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp | 2 ++ compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h | 7 +++++++ compiler-rt/lib/ubsan/ubsan_init_standalone.cpp | 7 +++++++ 5 files changed, 30 insertions(+) diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp index 96c41e9d42ba..6876be1dca53 100644 --- a/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -25,6 +25,11 @@ # include "asan_thread.h" # include "lsan/lsan_common.h" +namespace __sanitizer { +// ASan doesn't need to do anything else special in the startup hook. +void EarlySanitizerInit() {} +} // namespace __sanitizer + namespace __asan { // The system already set up the shadow memory for us. diff --git a/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp index d1696f8aa796..647211bf199e 100644 --- a/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp +++ b/compiler-rt/lib/hwasan/hwasan_fuchsia.cpp @@ -31,6 +31,15 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL uptr __hwasan_tls; +namespace __sanitizer { +void EarlySanitizerInit() { + // Setup the hwasan runtime before any `__libc_extensions_init`s are called. + // This is needed because libraries which define this function (like fdio) + // may be instrumented and either access `__hwasan_tls` or make runtime calls. + __hwasan_init(); +} +} // namespace __sanitizer + namespace __hwasan { bool InitShadow() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index acbf3ebfc95c..1ca50eb186a3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -547,6 +547,8 @@ void __sanitizer_startup_hook(int argc, char **argv, char **envp, __sanitizer::StoredEnviron = envp; __sanitizer::MainThreadStackBase = reinterpret_cast(stack_base); __sanitizer::MainThreadStackSize = stack_size; + + EarlySanitizerInit(); } void __sanitizer_set_report_path(const char *path) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h index 26c1deab9e5f..47e7537c1bdf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.h @@ -32,6 +32,13 @@ struct MemoryMappingLayoutData { void InitShadowBounds(); +// Individual sanitizers can define this to explicitly run something at the end +// of `__sanitizer_startup_hook`. This can be useful if a sanitizer needs to do +// extra work after the common startup hook code is called and before module +// ctors are invoked. For example, hwasan can explicitly call its initializing +// function here so it can be set up before libc extensions are initialized. +void EarlySanitizerInit(); + } // namespace __sanitizer #endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp b/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp index 91c3f57b424b..5083246b8b7f 100644 --- a/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp +++ b/compiler-rt/lib/ubsan/ubsan_init_standalone.cpp @@ -19,6 +19,13 @@ #include "ubsan_init.h" #include "ubsan_signals_standalone.h" +#if SANITIZER_FUCHSIA +namespace __sanitizer { +// UBSan doesn't need to do anything else special in the startup hook. +void EarlySanitizerInit() {} +} // namespace __sanitizer +#endif // SANITIZER_FUCHSIA + namespace __ubsan { class UbsanStandaloneInitializer {