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 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0; 47 SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler); 48} 49#define INIT_BSD_SIGNAL COMMON_INTERCEPT_FUNCTION(bsd_signal) 50#else // SANITIZER_INTERCEPT_BSD_SIGNAL 51#define INIT_BSD_SIGNAL 52#endif // SANITIZER_INTERCEPT_BSD_SIGNAL 53 54#if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 55INTERCEPTOR(uptr, signal, int signum, uptr handler) { 56 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) 57 return (uptr) nullptr; 58 SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler); 59} 60#define INIT_SIGNAL COMMON_INTERCEPT_FUNCTION(signal) 61 62INTERCEPTOR(int, sigaction_symname, int signum, 63 const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) { 64 if (GetHandleSignalMode(signum) == kHandleSignalExclusive) { 65 if (!oldact) return 0; 66 act = nullptr; 67 } 68 SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact); 69} 70#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname) 71 72namespace __sanitizer { 73int real_sigaction(int signum, const void *act, void *oldact) { 74 return REAL(sigaction_symname)(signum, (const __sanitizer_sigaction *)act, 75 (__sanitizer_sigaction *)oldact); 76} 77} // namespace __sanitizer 78#else // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 79#define INIT_SIGNAL 80#define INIT_SIGACTION 81// We need to have defined REAL(sigaction) on other systems. 82namespace __sanitizer { 83struct __sanitizer_sigaction; 84} 85DEFINE_REAL(int, sigaction, int signum, const __sanitizer_sigaction *act, 86 __sanitizer_sigaction *oldact) 87#endif // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION 88 89static void InitializeSignalInterceptors() { 90 static bool was_called_once; 91 CHECK(!was_called_once); 92 was_called_once = true; 93 94 INIT_BSD_SIGNAL; 95 INIT_SIGNAL; 96 INIT_SIGACTION; 97} 98