Home | History | Annotate | Line # | Download | only in ubsan
      1 //=-- ubsan_signals_standalone.cpp ----------------------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // Installs signal handlers and related interceptors for UBSan standalone.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #include "ubsan_platform.h"
     14 #include "sanitizer_common/sanitizer_platform.h"
     15 #if CAN_SANITIZE_UB
     16 #include "interception/interception.h"
     17 #include "sanitizer_common/sanitizer_stacktrace.h"
     18 #include "ubsan_diag.h"
     19 #include "ubsan_init.h"
     20 
     21 // Interception of signals breaks too many things on Android.
     22 // * It requires that ubsan is the first dependency of the main executable for
     23 // the interceptors to work correctly. This complicates deployment, as it
     24 // prevents us from enabling ubsan on random platform modules independently.
     25 // * For this to work with ART VM, ubsan signal handler has to be set after the
     26 // debuggerd handler, but before the ART handler.
     27 // * Interceptors don't work at all when ubsan runtime is loaded late, ex. when
     28 // it is part of an APK that does not use wrap.sh method.
     29 #if SANITIZER_FUCHSIA || SANITIZER_ANDROID
     30 
     31 namespace __ubsan {
     32 void InitializeDeadlySignals() {}
     33 }
     34 
     35 #else
     36 
     37 namespace __ubsan {
     38 void InitializeDeadlySignals();
     39 } // namespace __ubsan
     40 
     41 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
     42 #define SIGNAL_INTERCEPTOR_ENTER() __ubsan::InitializeDeadlySignals()
     43 #include "sanitizer_common/sanitizer_signal_interceptors.inc"
     44 
     45 // TODO(yln): Temporary workaround. Will be removed.
     46 void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
     47                          uptr pc, uptr bp, void *context, bool fast);
     48 
     49 namespace __ubsan {
     50 
     51 static void OnStackUnwind(const SignalContext &sig, const void *,
     52                           BufferedStackTrace *stack) {
     53   ubsan_GetStackTrace(stack, kStackTraceMax,
     54                       StackTrace::GetNextInstructionPc(sig.pc), sig.bp,
     55                       sig.context, common_flags()->fast_unwind_on_fatal);
     56 }
     57 
     58 static void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) {
     59   HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr);
     60 }
     61 
     62 static bool is_initialized = false;
     63 
     64 void InitializeDeadlySignals() {
     65   if (is_initialized)
     66     return;
     67   is_initialized = true;
     68   InitializeSignalInterceptors();
     69   InstallDeadlySignalHandlers(&UBsanOnDeadlySignal);
     70 }
     71 
     72 } // namespace __ubsan
     73 
     74 #endif
     75 
     76 #endif // CAN_SANITIZE_UB
     77