Home | History | Annotate | Download | only in asan
      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       CHECK(frames);
     93       for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
     94         const char *function_name = cur->info.function;
     95         if (!function_name) {
     96           continue;
     97         }
     98         // Match "interceptor_via_fun" suppressions.
     99         if (suppression_ctx->Match(function_name, kInterceptorViaFunction,
    100                                    &s)) {
    101           frames->ClearAll();
    102           return true;
    103         }
    104       }
    105       frames->ClearAll();
    106     }
    107   }
    108   return false;
    109 }
    110 
    111 } // namespace __asan
    112