1//===-- asan_suppressions.cc ----------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// Issue suppression and suppression-related functions. 13//===----------------------------------------------------------------------===// 14 15#include "asan_suppressions.h" 16 17#include "asan_stack.h" 18#include "sanitizer_common/sanitizer_placement_new.h" 19#include "sanitizer_common/sanitizer_suppressions.h" 20#include "sanitizer_common/sanitizer_symbolizer.h" 21 22namespace __asan { 23 24ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)]; 25static SuppressionContext *suppression_ctx = nullptr; 26static const char kInterceptorName[] = "interceptor_name"; 27static const char kInterceptorViaFunction[] = "interceptor_via_fun"; 28static const char kInterceptorViaLibrary[] = "interceptor_via_lib"; 29static const char kODRViolation[] = "odr_violation"; 30static const char *kSuppressionTypes[] = { 31 kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary, 32 kODRViolation}; 33 34extern "C" { 35#if SANITIZER_SUPPORTS_WEAK_HOOKS 36SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 37const char *__asan_default_suppressions(); 38#else 39// No week hooks, provide empty implementation. 40const char *__asan_default_suppressions() { return ""; } 41#endif // SANITIZER_SUPPORTS_WEAK_HOOKS 42} // extern "C" 43 44void InitializeSuppressions() { 45 CHECK_EQ(nullptr, suppression_ctx); 46 suppression_ctx = new (suppression_placeholder) // NOLINT 47 SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); 48 suppression_ctx->ParseFromFile(flags()->suppressions); 49 if (&__asan_default_suppressions) 50 suppression_ctx->Parse(__asan_default_suppressions()); 51} 52 53bool IsInterceptorSuppressed(const char *interceptor_name) { 54 CHECK(suppression_ctx); 55 Suppression *s; 56 // Match "interceptor_name" suppressions. 57 return suppression_ctx->Match(interceptor_name, kInterceptorName, &s); 58} 59 60bool HaveStackTraceBasedSuppressions() { 61 CHECK(suppression_ctx); 62 return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) || 63 suppression_ctx->HasSuppressionType(kInterceptorViaLibrary); 64} 65 66bool IsODRViolationSuppressed(const char *global_var_name) { 67 CHECK(suppression_ctx); 68 Suppression *s; 69 // Match "odr_violation" suppressions. 70 return suppression_ctx->Match(global_var_name, kODRViolation, &s); 71} 72 73bool IsStackTraceSuppressed(const StackTrace *stack) { 74 if (!HaveStackTraceBasedSuppressions()) 75 return false; 76 77 CHECK(suppression_ctx); 78 Symbolizer *symbolizer = Symbolizer::GetOrInit(); 79 Suppression *s; 80 for (uptr i = 0; i < stack->size && stack->trace[i]; i++) { 81 uptr addr = stack->trace[i]; 82 83 if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) { 84 // Match "interceptor_via_lib" suppressions. 85 if (const char *module_name = symbolizer->GetModuleNameForPc(addr)) 86 if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s)) 87 return true; 88 } 89 90 if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) { 91 SymbolizedStack *frames = symbolizer->SymbolizePC(addr); 92 for (SymbolizedStack *cur = frames; cur; cur = cur->next) { 93 const char *function_name = cur->info.function; 94 if (!function_name) { 95 continue; 96 } 97 // Match "interceptor_via_fun" suppressions. 98 if (suppression_ctx->Match(function_name, kInterceptorViaFunction, 99 &s)) { 100 frames->ClearAll(); 101 return true; 102 } 103 } 104 frames->ClearAll(); 105 } 106 } 107 return false; 108} 109 110} // namespace __asan 111