1//===-- asan_activation.cc --------------------------------------*- C++ -*-===// 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// ASan activation/deactivation logic. 13//===----------------------------------------------------------------------===// 14 15#include "asan_activation.h" 16#include "asan_allocator.h" 17#include "asan_flags.h" 18#include "asan_internal.h" 19#include "asan_poisoning.h" 20#include "asan_stack.h" 21#include "sanitizer_common/sanitizer_flags.h" 22 23namespace __asan { 24 25static struct AsanDeactivatedFlags { 26 AllocatorOptions allocator_options; 27 int malloc_context_size; 28 bool poison_heap; 29 bool coverage; 30 const char *coverage_dir; 31 32 void RegisterActivationFlags(FlagParser *parser, Flags *f, CommonFlags *cf) { 33#define ASAN_ACTIVATION_FLAG(Type, Name) \ 34 RegisterFlag(parser, #Name, "", &f->Name); 35#define COMMON_ACTIVATION_FLAG(Type, Name) \ 36 RegisterFlag(parser, #Name, "", &cf->Name); 37#include "asan_activation_flags.inc" 38#undef ASAN_ACTIVATION_FLAG 39#undef COMMON_ACTIVATION_FLAG 40 41 RegisterIncludeFlag(parser, cf); 42 } 43 44 void OverrideFromActivationFlags() { 45 Flags f; 46 CommonFlags cf; 47 FlagParser parser; 48 RegisterActivationFlags(&parser, &f, &cf); 49 50 // Copy the current activation flags. 51 allocator_options.CopyTo(&f, &cf); 52 cf.malloc_context_size = malloc_context_size; 53 f.poison_heap = poison_heap; 54 cf.coverage = coverage; 55 cf.coverage_dir = coverage_dir; 56 cf.verbosity = Verbosity(); 57 cf.help = false; // this is activation-specific help 58 59 // Check if activation flags need to be overriden. 60 if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) { 61 parser.ParseString(env); 62 } 63 64 // Override from getprop asan.options. 65 char buf[100]; 66 GetExtraActivationFlags(buf, sizeof(buf)); 67 parser.ParseString(buf); 68 69 SetVerbosity(cf.verbosity); 70 71 if (Verbosity()) ReportUnrecognizedFlags(); 72 73 if (cf.help) parser.PrintFlagDescriptions(); 74 75 allocator_options.SetFrom(&f, &cf); 76 malloc_context_size = cf.malloc_context_size; 77 poison_heap = f.poison_heap; 78 coverage = cf.coverage; 79 coverage_dir = cf.coverage_dir; 80 } 81 82 void Print() { 83 Report( 84 "quarantine_size_mb %d, max_redzone %d, poison_heap %d, " 85 "malloc_context_size %d, alloc_dealloc_mismatch %d, " 86 "allocator_may_return_null %d, coverage %d, coverage_dir %s\n", 87 allocator_options.quarantine_size_mb, allocator_options.max_redzone, 88 poison_heap, malloc_context_size, 89 allocator_options.alloc_dealloc_mismatch, 90 allocator_options.may_return_null, coverage, coverage_dir); 91 } 92} asan_deactivated_flags; 93 94static bool asan_is_deactivated; 95 96void AsanDeactivate() { 97 CHECK(!asan_is_deactivated); 98 VReport(1, "Deactivating ASan\n"); 99 100 // Stash runtime state. 101 GetAllocatorOptions(&asan_deactivated_flags.allocator_options); 102 asan_deactivated_flags.malloc_context_size = GetMallocContextSize(); 103 asan_deactivated_flags.poison_heap = CanPoisonMemory(); 104 asan_deactivated_flags.coverage = common_flags()->coverage; 105 asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir; 106 107 // Deactivate the runtime. 108 SetCanPoisonMemory(false); 109 SetMallocContextSize(1); 110 ReInitializeCoverage(false, nullptr); 111 112 AllocatorOptions disabled = asan_deactivated_flags.allocator_options; 113 disabled.quarantine_size_mb = 0; 114 disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. 115 disabled.max_redzone = 16; 116 disabled.alloc_dealloc_mismatch = false; 117 disabled.may_return_null = true; 118 ReInitializeAllocator(disabled); 119 120 asan_is_deactivated = true; 121} 122 123void AsanActivate() { 124 if (!asan_is_deactivated) return; 125 VReport(1, "Activating ASan\n"); 126 127 asan_deactivated_flags.OverrideFromActivationFlags(); 128 129 SetCanPoisonMemory(asan_deactivated_flags.poison_heap); 130 SetMallocContextSize(asan_deactivated_flags.malloc_context_size); 131 ReInitializeCoverage(asan_deactivated_flags.coverage, 132 asan_deactivated_flags.coverage_dir); 133 ReInitializeAllocator(asan_deactivated_flags.allocator_options); 134 135 asan_is_deactivated = false; 136 if (Verbosity()) { 137 Report("Activated with flags:\n"); 138 asan_deactivated_flags.Print(); 139 } 140} 141 142} // namespace __asan 143