1//===-- sanitizer_signal_interceptors.inc -----------------------*- C++ -*-===// 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// Signal interceptors for sanitizers. 10// 11//===----------------------------------------------------------------------===// 12 13#include "interception/interception.h" 14#include "sanitizer_common.h" 15#include "sanitizer_internal_defs.h" 16#include "sanitizer_platform_interceptors.h" 17 18using namespace __sanitizer; 19 20#if SANITIZER_NETBSD 21#define sigaction_symname __sigaction14 22#else 23#define sigaction_symname sigaction 24#endif 25 26#ifndef SIGNAL_INTERCEPTOR_SIGNAL_IMPL 27#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signum, handler) \ 28 { return REAL(func)(signum, handler); } 29#endif 30 31#ifndef SIGNAL_INTERCEPTOR_SIGACTION_IMPL 32# define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact) \ 33 { \ 34 if (!REAL(sigaction_symname)) { \ 35 Printf( \ 36 "Warning: REAL(sigaction_symname) == nullptr. This may happen " \ 37 "if you link with ubsan statically. Sigaction will not work.\n"); \ 38 return -1; \ 39 } \ 40 return REAL(sigaction_symname)(signum, act, oldact); \ 41 } 42#endif 43 44#if SANITIZER_INTERCEPT_BSD_SIGNAL 45INTERCEPTOR(uptr, bsd_signal, int signum, uptr handler) { 46 SIGNAL_INTERCEPTOR_ENTER(); 47 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0; 48 SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler); 49} 50#define INIT_BSD_SIGNAL COMMON_INTERCEPT_FUNCTION(bsd_signal) 51#else // SANITIZER_INTERCEPT_BSD_SIGNAL 52#define INIT_BSD_SIGNAL 53#endif // SANITIZER_INTERCEPT_BSD_SIGNAL 54 55#if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 56INTERCEPTOR(uptr, signal, int signum, uptr handler) { 57 SIGNAL_INTERCEPTOR_ENTER(); 58 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) 59 return (uptr) nullptr; 60 SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler); 61} 62#define INIT_SIGNAL COMMON_INTERCEPT_FUNCTION(signal) 63 64INTERCEPTOR(int, sigaction_symname, int signum, 65 const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) { 66 SIGNAL_INTERCEPTOR_ENTER(); 67 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) { 68 if (!oldact) return 0; 69 act = nullptr; 70 } 71 SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact); 72} 73#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname) 74 75namespace __sanitizer { 76int real_sigaction(int signum, const void *act, void *oldact) { 77 return REAL(sigaction_symname)(signum, (const __sanitizer_sigaction *)act, 78 (__sanitizer_sigaction *)oldact); 79} 80} // namespace __sanitizer 81#else // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 82#define INIT_SIGNAL 83#define INIT_SIGACTION 84// We need to have defined REAL(sigaction) on other systems. 85namespace __sanitizer { 86struct __sanitizer_sigaction; 87} 88DEFINE_REAL(int, sigaction, int signum, const __sanitizer_sigaction *act, 89 __sanitizer_sigaction *oldact) 90#endif // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 91 92static void InitializeSignalInterceptors() { 93 static bool was_called_once; 94 CHECK(!was_called_once); 95 was_called_once = true; 96 97 INIT_BSD_SIGNAL; 98 INIT_SIGNAL; 99 INIT_SIGACTION; 100} 101