[compiler-rt] [ubsan] Support static linking with standalone runtime (PR #80943)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 13 16:46:23 PST 2024


================
@@ -66,6 +66,11 @@ void InitializeDeadlySignals() {
     return;
   is_initialized = true;
   InitializeSignalInterceptors();
+#if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION
+  // REAL(sigaction_symname) is nullptr in a static link. Bail out.
+  if (!REAL(sigaction_symname))
----------------
MaskRay wrote:

> So as-is this patch introduce interceptor related logic into UBSAN, which would be nice to avoid
> 
> ```
> int internal_sigaction(int signum, const void *act, void *oldact) {
> #  if !SANITIZER_GO
>   if (&real_sigaction)
>     return real_sigaction(signum, act, oldact);
> #  endif
>   return sigaction(signum, (const struct sigaction *)act,
>                    (struct sigaction *)oldact);
> }
> ```
> 
> From this code, it already should throughout to `sigaction`, so it does not match the test in the description:
> 
> > with static linking
> > (-static/-static-pie), the called REAL(sigaction) is null, leading to
> > an immediate segfault,

The description is correct.
`real_sigaction` is defined due to `SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION`.
`real_sigaction` calls a function pointer, `REAL(sigaction)`, which is null in the static linking case.

> I think the best for -static is to avoid code
> 
>> #define SIGNAL_INTERCEPTOR_ENTER() __ubsan::InitializeDeadlySignals()
>> #include "sanitizer_common/sanitizer_signal_interceptors.inc"

Without the `!REAL(sigaction_symname)` check as done in this PR, just making `SIGNAL_INTERCEPTOR_ENTER` a no-op does not fix the static linking crash.

Yes, `ubsan_signals_standalone.cpp` defines the signal interceptors. ISTM adding a few lines in this file is the cleanest approach, in contract to an alternative that modifies a generic file which is not needed by another sanitizer.


https://github.com/llvm/llvm-project/pull/80943


More information about the llvm-commits mailing list