168d75effSDimitry Andric //===-- asan_suppressions.cpp ---------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is a part of AddressSanitizer, an address sanity checker.
1068d75effSDimitry Andric //
1168d75effSDimitry Andric // Issue suppression and suppression-related functions.
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric
1468d75effSDimitry Andric #include "asan_suppressions.h"
1568d75effSDimitry Andric
1668d75effSDimitry Andric #include "asan_stack.h"
1768d75effSDimitry Andric #include "sanitizer_common/sanitizer_placement_new.h"
1868d75effSDimitry Andric #include "sanitizer_common/sanitizer_suppressions.h"
1968d75effSDimitry Andric #include "sanitizer_common/sanitizer_symbolizer.h"
2068d75effSDimitry Andric
2168d75effSDimitry Andric namespace __asan {
2268d75effSDimitry Andric
23*0fca6ea1SDimitry Andric alignas(64) static char suppression_placeholder[sizeof(SuppressionContext)];
2468d75effSDimitry Andric static SuppressionContext *suppression_ctx = nullptr;
2568d75effSDimitry Andric static const char kInterceptorName[] = "interceptor_name";
2668d75effSDimitry Andric static const char kInterceptorViaFunction[] = "interceptor_via_fun";
2768d75effSDimitry Andric static const char kInterceptorViaLibrary[] = "interceptor_via_lib";
2868d75effSDimitry Andric static const char kODRViolation[] = "odr_violation";
2968d75effSDimitry Andric static const char *kSuppressionTypes[] = {
3068d75effSDimitry Andric kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary,
3168d75effSDimitry Andric kODRViolation};
3268d75effSDimitry Andric
SANITIZER_INTERFACE_WEAK_DEF(const char *,__asan_default_suppressions,void)3368d75effSDimitry Andric SANITIZER_INTERFACE_WEAK_DEF(const char *, __asan_default_suppressions, void) {
3468d75effSDimitry Andric return "";
3568d75effSDimitry Andric }
3668d75effSDimitry Andric
InitializeSuppressions()3768d75effSDimitry Andric void InitializeSuppressions() {
3868d75effSDimitry Andric CHECK_EQ(nullptr, suppression_ctx);
3968d75effSDimitry Andric suppression_ctx = new (suppression_placeholder)
4068d75effSDimitry Andric SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
4168d75effSDimitry Andric suppression_ctx->ParseFromFile(flags()->suppressions);
4268d75effSDimitry Andric suppression_ctx->Parse(__asan_default_suppressions());
4368d75effSDimitry Andric }
4468d75effSDimitry Andric
IsInterceptorSuppressed(const char * interceptor_name)4568d75effSDimitry Andric bool IsInterceptorSuppressed(const char *interceptor_name) {
4668d75effSDimitry Andric CHECK(suppression_ctx);
4768d75effSDimitry Andric Suppression *s;
4868d75effSDimitry Andric // Match "interceptor_name" suppressions.
4968d75effSDimitry Andric return suppression_ctx->Match(interceptor_name, kInterceptorName, &s);
5068d75effSDimitry Andric }
5168d75effSDimitry Andric
HaveStackTraceBasedSuppressions()5268d75effSDimitry Andric bool HaveStackTraceBasedSuppressions() {
5368d75effSDimitry Andric CHECK(suppression_ctx);
5468d75effSDimitry Andric return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) ||
5568d75effSDimitry Andric suppression_ctx->HasSuppressionType(kInterceptorViaLibrary);
5668d75effSDimitry Andric }
5768d75effSDimitry Andric
IsODRViolationSuppressed(const char * global_var_name)5868d75effSDimitry Andric bool IsODRViolationSuppressed(const char *global_var_name) {
5968d75effSDimitry Andric CHECK(suppression_ctx);
6068d75effSDimitry Andric Suppression *s;
6168d75effSDimitry Andric // Match "odr_violation" suppressions.
6268d75effSDimitry Andric return suppression_ctx->Match(global_var_name, kODRViolation, &s);
6368d75effSDimitry Andric }
6468d75effSDimitry Andric
IsStackTraceSuppressed(const StackTrace * stack)6568d75effSDimitry Andric bool IsStackTraceSuppressed(const StackTrace *stack) {
6668d75effSDimitry Andric if (!HaveStackTraceBasedSuppressions())
6768d75effSDimitry Andric return false;
6868d75effSDimitry Andric
6968d75effSDimitry Andric CHECK(suppression_ctx);
7068d75effSDimitry Andric Symbolizer *symbolizer = Symbolizer::GetOrInit();
7168d75effSDimitry Andric Suppression *s;
7268d75effSDimitry Andric for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
7368d75effSDimitry Andric uptr addr = stack->trace[i];
7468d75effSDimitry Andric
7568d75effSDimitry Andric if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) {
7668d75effSDimitry Andric // Match "interceptor_via_lib" suppressions.
7768d75effSDimitry Andric if (const char *module_name = symbolizer->GetModuleNameForPc(addr))
7868d75effSDimitry Andric if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s))
7968d75effSDimitry Andric return true;
8068d75effSDimitry Andric }
8168d75effSDimitry Andric
8268d75effSDimitry Andric if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) {
831db9f3b2SDimitry Andric SymbolizedStackHolder symbolized_stack(symbolizer->SymbolizePC(addr));
841db9f3b2SDimitry Andric const SymbolizedStack *frames = symbolized_stack.get();
8568d75effSDimitry Andric CHECK(frames);
861db9f3b2SDimitry Andric for (const SymbolizedStack *cur = frames; cur; cur = cur->next) {
8768d75effSDimitry Andric const char *function_name = cur->info.function;
8868d75effSDimitry Andric if (!function_name) {
8968d75effSDimitry Andric continue;
9068d75effSDimitry Andric }
9168d75effSDimitry Andric // Match "interceptor_via_fun" suppressions.
9268d75effSDimitry Andric if (suppression_ctx->Match(function_name, kInterceptorViaFunction,
9368d75effSDimitry Andric &s)) {
9468d75effSDimitry Andric return true;
9568d75effSDimitry Andric }
9668d75effSDimitry Andric }
9768d75effSDimitry Andric }
9868d75effSDimitry Andric }
9968d75effSDimitry Andric return false;
10068d75effSDimitry Andric }
10168d75effSDimitry Andric
10268d75effSDimitry Andric } // namespace __asan
103