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 22 namespace __asan { 23 24 ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)]; 25 static SuppressionContext *suppression_ctx = nullptr; 26 static const char kInterceptorName[] = "interceptor_name"; 27 static const char kInterceptorViaFunction[] = "interceptor_via_fun"; 28 static const char kInterceptorViaLibrary[] = "interceptor_via_lib"; 29 static const char kODRViolation[] = "odr_violation"; 30 static const char *kSuppressionTypes[] = { 31 kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary, 32 kODRViolation}; 33 34 SANITIZER_INTERFACE_WEAK_DEF(const char *, __asan_default_suppressions, void) { 35 return ""; 36 } 37 38 void InitializeSuppressions() { 39 CHECK_EQ(nullptr, suppression_ctx); 40 suppression_ctx = new (suppression_placeholder) // NOLINT 41 SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); 42 suppression_ctx->ParseFromFile(flags()->suppressions); 43 if (&__asan_default_suppressions) 44 suppression_ctx->Parse(__asan_default_suppressions()); 45 } 46 47 bool IsInterceptorSuppressed(const char *interceptor_name) { 48 CHECK(suppression_ctx); 49 Suppression *s; 50 // Match "interceptor_name" suppressions. 51 return suppression_ctx->Match(interceptor_name, kInterceptorName, &s); 52 } 53 54 bool HaveStackTraceBasedSuppressions() { 55 CHECK(suppression_ctx); 56 return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) || 57 suppression_ctx->HasSuppressionType(kInterceptorViaLibrary); 58 } 59 60 bool IsODRViolationSuppressed(const char *global_var_name) { 61 CHECK(suppression_ctx); 62 Suppression *s; 63 // Match "odr_violation" suppressions. 64 return suppression_ctx->Match(global_var_name, kODRViolation, &s); 65 } 66 67 bool IsStackTraceSuppressed(const StackTrace *stack) { 68 if (!HaveStackTraceBasedSuppressions()) 69 return false; 70 71 CHECK(suppression_ctx); 72 Symbolizer *symbolizer = Symbolizer::GetOrInit(); 73 Suppression *s; 74 for (uptr i = 0; i < stack->size && stack->trace[i]; i++) { 75 uptr addr = stack->trace[i]; 76 77 if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) { 78 // Match "interceptor_via_lib" suppressions. 79 if (const char *module_name = symbolizer->GetModuleNameForPc(addr)) 80 if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s)) 81 return true; 82 } 83 84 if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) { 85 SymbolizedStack *frames = symbolizer->SymbolizePC(addr); 86 CHECK(frames); 87 for (SymbolizedStack *cur = frames; cur; cur = cur->next) { 88 const char *function_name = cur->info.function; 89 if (!function_name) { 90 continue; 91 } 92 // Match "interceptor_via_fun" suppressions. 93 if (suppression_ctx->Match(function_name, kInterceptorViaFunction, 94 &s)) { 95 frames->ClearAll(); 96 return true; 97 } 98 } 99 frames->ClearAll(); 100 } 101 } 102 return false; 103 } 104 105 } // namespace __asan 106