168d75effSDimitry Andric //===-- asan_activation.cpp -------------------------------------*- C++ -*-===//
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 // ASan activation/deactivation logic.
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric
1468d75effSDimitry Andric #include "asan_activation.h"
1568d75effSDimitry Andric #include "asan_allocator.h"
1668d75effSDimitry Andric #include "asan_flags.h"
1768d75effSDimitry Andric #include "asan_internal.h"
1868d75effSDimitry Andric #include "asan_mapping.h"
1968d75effSDimitry Andric #include "asan_poisoning.h"
2068d75effSDimitry Andric #include "asan_stack.h"
2168d75effSDimitry Andric #include "sanitizer_common/sanitizer_common.h"
2268d75effSDimitry Andric #include "sanitizer_common/sanitizer_flags.h"
2368d75effSDimitry Andric
2468d75effSDimitry Andric namespace __asan {
2568d75effSDimitry Andric
2668d75effSDimitry Andric static struct AsanDeactivatedFlags {
2768d75effSDimitry Andric AllocatorOptions allocator_options;
2868d75effSDimitry Andric int malloc_context_size;
2968d75effSDimitry Andric bool poison_heap;
3068d75effSDimitry Andric bool coverage;
3168d75effSDimitry Andric const char *coverage_dir;
3268d75effSDimitry Andric
RegisterActivationFlags__asan::AsanDeactivatedFlags3368d75effSDimitry Andric void RegisterActivationFlags(FlagParser *parser, Flags *f, CommonFlags *cf) {
3468d75effSDimitry Andric #define ASAN_ACTIVATION_FLAG(Type, Name) \
3568d75effSDimitry Andric RegisterFlag(parser, #Name, "", &f->Name);
3668d75effSDimitry Andric #define COMMON_ACTIVATION_FLAG(Type, Name) \
3768d75effSDimitry Andric RegisterFlag(parser, #Name, "", &cf->Name);
3868d75effSDimitry Andric #include "asan_activation_flags.inc"
3968d75effSDimitry Andric #undef ASAN_ACTIVATION_FLAG
4068d75effSDimitry Andric #undef COMMON_ACTIVATION_FLAG
4168d75effSDimitry Andric
4268d75effSDimitry Andric RegisterIncludeFlags(parser, cf);
4368d75effSDimitry Andric }
4468d75effSDimitry Andric
OverrideFromActivationFlags__asan::AsanDeactivatedFlags4568d75effSDimitry Andric void OverrideFromActivationFlags() {
4668d75effSDimitry Andric Flags f;
4768d75effSDimitry Andric CommonFlags cf;
4868d75effSDimitry Andric FlagParser parser;
4968d75effSDimitry Andric RegisterActivationFlags(&parser, &f, &cf);
5068d75effSDimitry Andric
5168d75effSDimitry Andric cf.SetDefaults();
5268d75effSDimitry Andric // Copy the current activation flags.
5368d75effSDimitry Andric allocator_options.CopyTo(&f, &cf);
5468d75effSDimitry Andric cf.malloc_context_size = malloc_context_size;
5568d75effSDimitry Andric f.poison_heap = poison_heap;
5668d75effSDimitry Andric cf.coverage = coverage;
5768d75effSDimitry Andric cf.coverage_dir = coverage_dir;
5868d75effSDimitry Andric cf.verbosity = Verbosity();
5968d75effSDimitry Andric cf.help = false; // this is activation-specific help
6068d75effSDimitry Andric
6168d75effSDimitry Andric // Check if activation flags need to be overriden.
6268d75effSDimitry Andric if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) {
6368d75effSDimitry Andric parser.ParseString(env);
6468d75effSDimitry Andric }
6568d75effSDimitry Andric
6668d75effSDimitry Andric InitializeCommonFlags(&cf);
6768d75effSDimitry Andric
6868d75effSDimitry Andric if (Verbosity()) ReportUnrecognizedFlags();
6968d75effSDimitry Andric
7068d75effSDimitry Andric if (cf.help) parser.PrintFlagDescriptions();
7168d75effSDimitry Andric
7268d75effSDimitry Andric allocator_options.SetFrom(&f, &cf);
7368d75effSDimitry Andric malloc_context_size = cf.malloc_context_size;
7468d75effSDimitry Andric poison_heap = f.poison_heap;
7568d75effSDimitry Andric coverage = cf.coverage;
7668d75effSDimitry Andric coverage_dir = cf.coverage_dir;
7768d75effSDimitry Andric }
7868d75effSDimitry Andric
Print__asan::AsanDeactivatedFlags7968d75effSDimitry Andric void Print() {
8068d75effSDimitry Andric Report(
8168d75effSDimitry Andric "quarantine_size_mb %d, thread_local_quarantine_size_kb %d, "
8268d75effSDimitry Andric "max_redzone %d, poison_heap %d, malloc_context_size %d, "
8368d75effSDimitry Andric "alloc_dealloc_mismatch %d, allocator_may_return_null %d, coverage %d, "
8468d75effSDimitry Andric "coverage_dir %s, allocator_release_to_os_interval_ms %d\n",
8568d75effSDimitry Andric allocator_options.quarantine_size_mb,
8668d75effSDimitry Andric allocator_options.thread_local_quarantine_size_kb,
8768d75effSDimitry Andric allocator_options.max_redzone, poison_heap, malloc_context_size,
8868d75effSDimitry Andric allocator_options.alloc_dealloc_mismatch,
8968d75effSDimitry Andric allocator_options.may_return_null, coverage, coverage_dir,
9068d75effSDimitry Andric allocator_options.release_to_os_interval_ms);
9168d75effSDimitry Andric }
9268d75effSDimitry Andric } asan_deactivated_flags;
9368d75effSDimitry Andric
9468d75effSDimitry Andric static bool asan_is_deactivated;
9568d75effSDimitry Andric
AsanDeactivate()9668d75effSDimitry Andric void AsanDeactivate() {
9768d75effSDimitry Andric CHECK(!asan_is_deactivated);
9868d75effSDimitry Andric VReport(1, "Deactivating ASan\n");
9968d75effSDimitry Andric
10068d75effSDimitry Andric // Stash runtime state.
10168d75effSDimitry Andric GetAllocatorOptions(&asan_deactivated_flags.allocator_options);
10268d75effSDimitry Andric asan_deactivated_flags.malloc_context_size = GetMallocContextSize();
10368d75effSDimitry Andric asan_deactivated_flags.poison_heap = CanPoisonMemory();
10468d75effSDimitry Andric asan_deactivated_flags.coverage = common_flags()->coverage;
10568d75effSDimitry Andric asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir;
10668d75effSDimitry Andric
10768d75effSDimitry Andric // Deactivate the runtime.
10868d75effSDimitry Andric SetCanPoisonMemory(false);
10968d75effSDimitry Andric SetMallocContextSize(1);
11068d75effSDimitry Andric
11168d75effSDimitry Andric AllocatorOptions disabled = asan_deactivated_flags.allocator_options;
11268d75effSDimitry Andric disabled.quarantine_size_mb = 0;
11368d75effSDimitry Andric disabled.thread_local_quarantine_size_kb = 0;
11468d75effSDimitry Andric // Redzone must be at least Max(16, granularity) bytes long.
115*0eae32dcSDimitry Andric disabled.min_redzone = Max(16, (int)ASAN_SHADOW_GRANULARITY);
11668d75effSDimitry Andric disabled.max_redzone = disabled.min_redzone;
11768d75effSDimitry Andric disabled.alloc_dealloc_mismatch = false;
11868d75effSDimitry Andric disabled.may_return_null = true;
11968d75effSDimitry Andric ReInitializeAllocator(disabled);
12068d75effSDimitry Andric
12168d75effSDimitry Andric asan_is_deactivated = true;
12268d75effSDimitry Andric }
12368d75effSDimitry Andric
AsanActivate()12468d75effSDimitry Andric void AsanActivate() {
12568d75effSDimitry Andric if (!asan_is_deactivated) return;
12668d75effSDimitry Andric VReport(1, "Activating ASan\n");
12768d75effSDimitry Andric
12868d75effSDimitry Andric UpdateProcessName();
12968d75effSDimitry Andric
13068d75effSDimitry Andric asan_deactivated_flags.OverrideFromActivationFlags();
13168d75effSDimitry Andric
13268d75effSDimitry Andric SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
13368d75effSDimitry Andric SetMallocContextSize(asan_deactivated_flags.malloc_context_size);
13468d75effSDimitry Andric ReInitializeAllocator(asan_deactivated_flags.allocator_options);
13568d75effSDimitry Andric
13668d75effSDimitry Andric asan_is_deactivated = false;
13768d75effSDimitry Andric if (Verbosity()) {
13868d75effSDimitry Andric Report("Activated with flags:\n");
13968d75effSDimitry Andric asan_deactivated_flags.Print();
14068d75effSDimitry Andric }
14168d75effSDimitry Andric }
14268d75effSDimitry Andric
14368d75effSDimitry Andric } // namespace __asan
144