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 23 namespace __asan { 24 25 static 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 RegisterIncludeFlags(parser, cf); 42 } 43 44 void OverrideFromActivationFlags() { 45 Flags f; 46 CommonFlags cf; 47 FlagParser parser; 48 RegisterActivationFlags(&parser, &f, &cf); 49 50 cf.SetDefaults(); 51 // Copy the current activation flags. 52 allocator_options.CopyTo(&f, &cf); 53 cf.malloc_context_size = malloc_context_size; 54 f.poison_heap = poison_heap; 55 cf.coverage = coverage; 56 cf.coverage_dir = coverage_dir; 57 cf.verbosity = Verbosity(); 58 cf.help = false; // this is activation-specific help 59 60 // Check if activation flags need to be overriden. 61 if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) { 62 parser.ParseString(env); 63 } 64 65 InitializeCommonFlags(&cf); 66 67 if (Verbosity()) ReportUnrecognizedFlags(); 68 69 if (cf.help) parser.PrintFlagDescriptions(); 70 71 allocator_options.SetFrom(&f, &cf); 72 malloc_context_size = cf.malloc_context_size; 73 poison_heap = f.poison_heap; 74 coverage = cf.coverage; 75 coverage_dir = cf.coverage_dir; 76 } 77 78 void Print() { 79 Report( 80 "quarantine_size_mb %d, max_redzone %d, poison_heap %d, " 81 "malloc_context_size %d, alloc_dealloc_mismatch %d, " 82 "allocator_may_return_null %d, coverage %d, coverage_dir %s\n", 83 allocator_options.quarantine_size_mb, allocator_options.max_redzone, 84 poison_heap, malloc_context_size, 85 allocator_options.alloc_dealloc_mismatch, 86 allocator_options.may_return_null, coverage, coverage_dir); 87 } 88 } asan_deactivated_flags; 89 90 static bool asan_is_deactivated; 91 92 void AsanDeactivate() { 93 CHECK(!asan_is_deactivated); 94 VReport(1, "Deactivating ASan\n"); 95 96 // Stash runtime state. 97 GetAllocatorOptions(&asan_deactivated_flags.allocator_options); 98 asan_deactivated_flags.malloc_context_size = GetMallocContextSize(); 99 asan_deactivated_flags.poison_heap = CanPoisonMemory(); 100 asan_deactivated_flags.coverage = common_flags()->coverage; 101 asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir; 102 103 // Deactivate the runtime. 104 SetCanPoisonMemory(false); 105 SetMallocContextSize(1); 106 ReInitializeCoverage(false, nullptr); 107 108 AllocatorOptions disabled = asan_deactivated_flags.allocator_options; 109 disabled.quarantine_size_mb = 0; 110 disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. 111 disabled.max_redzone = 16; 112 disabled.alloc_dealloc_mismatch = false; 113 disabled.may_return_null = true; 114 ReInitializeAllocator(disabled); 115 116 asan_is_deactivated = true; 117 } 118 119 void AsanActivate() { 120 if (!asan_is_deactivated) return; 121 VReport(1, "Activating ASan\n"); 122 123 UpdateProcessName(); 124 125 asan_deactivated_flags.OverrideFromActivationFlags(); 126 127 SetCanPoisonMemory(asan_deactivated_flags.poison_heap); 128 SetMallocContextSize(asan_deactivated_flags.malloc_context_size); 129 ReInitializeCoverage(asan_deactivated_flags.coverage, 130 asan_deactivated_flags.coverage_dir); 131 ReInitializeAllocator(asan_deactivated_flags.allocator_options); 132 133 asan_is_deactivated = false; 134 if (Verbosity()) { 135 Report("Activated with flags:\n"); 136 asan_deactivated_flags.Print(); 137 } 138 } 139 140 } // namespace __asan 141