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