168d75effSDimitry Andric //=-- ubsan_signals_standalone.cpp ----------------------------------------===// 268d75effSDimitry Andric // 368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 668d75effSDimitry Andric // 768d75effSDimitry Andric //===----------------------------------------------------------------------===// 868d75effSDimitry Andric // 968d75effSDimitry Andric // Installs signal handlers and related interceptors for UBSan standalone. 1068d75effSDimitry Andric // 1168d75effSDimitry Andric //===----------------------------------------------------------------------===// 1268d75effSDimitry Andric 1368d75effSDimitry Andric #include "ubsan_platform.h" 1468d75effSDimitry Andric #include "sanitizer_common/sanitizer_platform.h" 1568d75effSDimitry Andric #if CAN_SANITIZE_UB 1668d75effSDimitry Andric #include "interception/interception.h" 1768d75effSDimitry Andric #include "sanitizer_common/sanitizer_stacktrace.h" 1868d75effSDimitry Andric #include "ubsan_diag.h" 1968d75effSDimitry Andric #include "ubsan_init.h" 2068d75effSDimitry Andric 2168d75effSDimitry Andric // Interception of signals breaks too many things on Android. 2268d75effSDimitry Andric // * It requires that ubsan is the first dependency of the main executable for 2368d75effSDimitry Andric // the interceptors to work correctly. This complicates deployment, as it 2468d75effSDimitry Andric // prevents us from enabling ubsan on random platform modules independently. 2568d75effSDimitry Andric // * For this to work with ART VM, ubsan signal handler has to be set after the 2668d75effSDimitry Andric // debuggerd handler, but before the ART handler. 2768d75effSDimitry Andric // * Interceptors don't work at all when ubsan runtime is loaded late, ex. when 2868d75effSDimitry Andric // it is part of an APK that does not use wrap.sh method. 2968d75effSDimitry Andric #if SANITIZER_FUCHSIA || SANITIZER_ANDROID 3068d75effSDimitry Andric 3168d75effSDimitry Andric namespace __ubsan { 3268d75effSDimitry Andric void InitializeDeadlySignals() {} 3368d75effSDimitry Andric } 3468d75effSDimitry Andric 3568d75effSDimitry Andric #else 3668d75effSDimitry Andric 3706c3fb27SDimitry Andric namespace __ubsan { 3806c3fb27SDimitry Andric void InitializeDeadlySignals(); 3906c3fb27SDimitry Andric } // namespace __ubsan 4006c3fb27SDimitry Andric 4168d75effSDimitry Andric #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) 4206c3fb27SDimitry Andric #define SIGNAL_INTERCEPTOR_ENTER() __ubsan::InitializeDeadlySignals() 4368d75effSDimitry Andric #include "sanitizer_common/sanitizer_signal_interceptors.inc" 4468d75effSDimitry Andric 4568d75effSDimitry Andric // TODO(yln): Temporary workaround. Will be removed. 4668d75effSDimitry Andric void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth, 4768d75effSDimitry Andric uptr pc, uptr bp, void *context, bool fast); 4868d75effSDimitry Andric 4968d75effSDimitry Andric namespace __ubsan { 5068d75effSDimitry Andric 5168d75effSDimitry Andric static void OnStackUnwind(const SignalContext &sig, const void *, 5268d75effSDimitry Andric BufferedStackTrace *stack) { 5368d75effSDimitry Andric ubsan_GetStackTrace(stack, kStackTraceMax, 5468d75effSDimitry Andric StackTrace::GetNextInstructionPc(sig.pc), sig.bp, 5568d75effSDimitry Andric sig.context, common_flags()->fast_unwind_on_fatal); 5668d75effSDimitry Andric } 5768d75effSDimitry Andric 5868d75effSDimitry Andric static void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) { 5968d75effSDimitry Andric HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); 6068d75effSDimitry Andric } 6168d75effSDimitry Andric 6268d75effSDimitry Andric static bool is_initialized = false; 6368d75effSDimitry Andric 6468d75effSDimitry Andric void InitializeDeadlySignals() { 6568d75effSDimitry Andric if (is_initialized) 6668d75effSDimitry Andric return; 6768d75effSDimitry Andric is_initialized = true; 6868d75effSDimitry Andric InitializeSignalInterceptors(); 69*0fca6ea1SDimitry Andric #if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 70*0fca6ea1SDimitry Andric // REAL(sigaction_symname) is nullptr in a static link. Bail out. 71*0fca6ea1SDimitry Andric if (!REAL(sigaction_symname)) 72*0fca6ea1SDimitry Andric return; 73*0fca6ea1SDimitry Andric #endif 7468d75effSDimitry Andric InstallDeadlySignalHandlers(&UBsanOnDeadlySignal); 7568d75effSDimitry Andric } 7668d75effSDimitry Andric 7768d75effSDimitry Andric } // namespace __ubsan 7868d75effSDimitry Andric 7968d75effSDimitry Andric #endif 8068d75effSDimitry Andric 8168d75effSDimitry Andric #endif // CAN_SANITIZE_UB 82