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 extern "C" { 35 #if SANITIZER_SUPPORTS_WEAK_HOOKS 36 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 37 const char *__asan_default_suppressions(); 38 #else 39 // No week hooks, provide empty implementation. 40 const char *__asan_default_suppressions() { return ""; } 41 #endif // SANITIZER_SUPPORTS_WEAK_HOOKS 42 } // extern "C" 43 44 void 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 53 bool 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 60 bool HaveStackTraceBasedSuppressions() { 61 CHECK(suppression_ctx); 62 return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) || 63 suppression_ctx->HasSuppressionType(kInterceptorViaLibrary); 64 } 65 66 bool 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 73 bool 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