brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 8511e4d Raw
139 lines · plain
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-exception6//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_NETBSD21#define sigaction_symname __sigaction1422#else23#define sigaction_symname sigaction24#endif25 26#ifndef SIGNAL_INTERCEPTOR_SIGNAL_IMPL27#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signum, handler) \28  { return REAL(func)(signum, handler); }29#endif30 31#ifndef SIGNAL_INTERCEPTOR_SIGACTION_IMPL32#  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#endif43 44#if SANITIZER_INTERCEPT_BSD_SIGNAL45INTERCEPTOR(uptr, bsd_signal, int signum, uptr handler) {46  SIGNAL_INTERCEPTOR_ENTER();47  if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0;48 49  // TODO: support cloak_sanitizer_signal_handlers50  SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler);51}52#define INIT_BSD_SIGNAL COMMON_INTERCEPT_FUNCTION(bsd_signal)53#else  // SANITIZER_INTERCEPT_BSD_SIGNAL54#define INIT_BSD_SIGNAL55#endif  // SANITIZER_INTERCEPT_BSD_SIGNAL56 57#if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION58INTERCEPTOR(uptr, signal, int signum, uptr handler) {59  SIGNAL_INTERCEPTOR_ENTER();60  if (GetHandleSignalMode(signum) == kHandleSignalExclusive)61    // The user can neither view nor change the signal handler, regardless of62    // the cloak_sanitizer_signal_handlers setting. This differs from63    // sigaction().64    return (uptr) nullptr;65 66  uptr ret = +[](auto signal, int signum, uptr handler) {67    SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler);68  }(signal, signum, handler);69 70  if (ret != sig_err && SetSignalHandlerFromSanitizer(signum, false))71    // If the user sets a signal handler, it becomes uncloaked, even if they72    // reuse a sanitizer's signal handler.73    ret = sig_dfl;74 75  return ret;76}77#define INIT_SIGNAL COMMON_INTERCEPT_FUNCTION(signal)78 79INTERCEPTOR(int, sigaction_symname, int signum,80            const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) {81  SIGNAL_INTERCEPTOR_ENTER();82 83  if (GetHandleSignalMode(signum) == kHandleSignalExclusive) {84    if (!oldact) return 0;85    act = nullptr;86    // If cloak_sanitizer_signal_handlers=true, the user can neither view nor87    // change the signal handle.88    // If false, the user can view but not change the signal handler. This89    // differs from signal().90  }91 92  int ret = +[](int signum, const __sanitizer_sigaction* act,93                __sanitizer_sigaction* oldact) {94    SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact);95  }(signum, act, oldact);96 97  if (act) {98    if (ret == 0 && SetSignalHandlerFromSanitizer(signum, false)) {99      // If the user sets a signal handler, it becomes uncloaked, even if they100      // reuse a sanitizer's signal handler.101 102      if (oldact)103        oldact->handler = reinterpret_cast<__sanitizer_sighandler_ptr>(sig_dfl);104    }105  } else if (ret == 0 && oldact && IsSignalHandlerFromSanitizer(signum)) {106    oldact->handler = reinterpret_cast<__sanitizer_sighandler_ptr>(sig_dfl);107  }108 109  return ret;110}111#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname)112 113namespace __sanitizer {114int real_sigaction(int signum, const void *act, void *oldact) {115  return REAL(sigaction_symname)(signum, (const __sanitizer_sigaction *)act,116                         (__sanitizer_sigaction *)oldact);117}118}  // namespace __sanitizer119#else  // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION120#define INIT_SIGNAL121#define INIT_SIGACTION122// We need to have defined REAL(sigaction) on other systems.123namespace __sanitizer {124struct __sanitizer_sigaction;125}126DEFINE_REAL(int, sigaction, int signum, const __sanitizer_sigaction *act,127            __sanitizer_sigaction *oldact)128#endif  // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION129 130static void InitializeSignalInterceptors() {131  static bool was_called_once;132  CHECK(!was_called_once);133  was_called_once = true;134 135  INIT_BSD_SIGNAL;136  INIT_SIGNAL;137  INIT_SIGACTION;138}139