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