Home | History | Annotate | Line # | 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 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