1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
//===-- asan_suppressions.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// Issue suppression and suppression-related functions.
//===----------------------------------------------------------------------===//
#include "asan_suppressions.h"
#include "asan_stack.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_suppressions.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
namespace __asan {
alignas(64) static char suppression_placeholder[sizeof(SuppressionContext)];
static SuppressionContext *suppression_ctx = nullptr;
static const char kInterceptorName[] = "interceptor_name";
static const char kInterceptorViaFunction[] = "interceptor_via_fun";
static const char kInterceptorViaLibrary[] = "interceptor_via_lib";
static const char kODRViolation[] = "odr_violation";
static const char kAllocDeallocMismatch[] = "alloc_dealloc_mismatch";
static const char *kSuppressionTypes[] = {
kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary,
kODRViolation, kAllocDeallocMismatch};
SANITIZER_INTERFACE_WEAK_DEF(const char *, __asan_default_suppressions, void) {
return "";
}
void InitializeSuppressions() {
CHECK_EQ(nullptr, suppression_ctx);
suppression_ctx = new (suppression_placeholder)
SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
suppression_ctx->ParseFromFile(flags()->suppressions);
suppression_ctx->Parse(__asan_default_suppressions());
}
bool IsInterceptorSuppressed(const char *interceptor_name) {
CHECK(suppression_ctx);
Suppression *s;
// Match "interceptor_name" suppressions.
return suppression_ctx->Match(interceptor_name, kInterceptorName, &s);
}
bool HaveStackTraceBasedSuppressions() {
CHECK(suppression_ctx);
return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) ||
suppression_ctx->HasSuppressionType(kInterceptorViaLibrary);
}
bool IsODRViolationSuppressed(const char *global_var_name) {
CHECK(suppression_ctx);
Suppression *s;
// Match "odr_violation" suppressions.
return suppression_ctx->Match(global_var_name, kODRViolation, &s);
}
bool IsAddrSuppressed(const char *suppression, Symbolizer *symbolizer,
uptr addr) {
CHECK(suppression_ctx);
CHECK(suppression_ctx->HasSuppressionType(suppression));
CHECK(symbolizer);
SymbolizedStackHolder symbolized_stack(symbolizer->SymbolizePC(addr));
const SymbolizedStack *frames = symbolized_stack.get();
CHECK(frames);
for (const SymbolizedStack *cur = frames; cur; cur = cur->next) {
const char *function_name = cur->info.function;
if (!function_name) {
continue;
}
// Match suppressions.
Suppression *s;
if (suppression_ctx->Match(function_name, suppression, &s)) {
return true;
}
}
return false;
}
bool IsAllocDeallocMismatchSuppressed(const StackTrace *stack) {
CHECK(suppression_ctx);
if (!suppression_ctx->HasSuppressionType(kAllocDeallocMismatch)) {
return false;
}
Symbolizer *symbolizer = Symbolizer::GetOrInit();
for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
uptr addr = stack->trace[i];
// Match "alloc_dealloc_mismatch" suppressions.
if (IsAddrSuppressed(kAllocDeallocMismatch, symbolizer, addr)) {
return true;
}
}
return false;
}
bool IsStackTraceSuppressed(const StackTrace *stack) {
if (!HaveStackTraceBasedSuppressions())
return false;
CHECK(suppression_ctx);
Symbolizer *symbolizer = Symbolizer::GetOrInit();
Suppression *s;
for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
uptr addr = stack->trace[i];
if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) {
// Match "interceptor_via_lib" suppressions.
if (const char *module_name = symbolizer->GetModuleNameForPc(addr))
if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s))
return true;
}
if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) {
// Match "interceptor_via_func" suppressions.
if (IsAddrSuppressed(kInterceptorViaFunction, symbolizer, addr)) {
return true;
}
}
}
return false;
}
} // namespace __asan
|