12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===-- asan_activation.cc --------------------------------------*- C++ -*-===// 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is distributed under the University of Illinois Open Source 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// License. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is a part of AddressSanitizer, an address sanity checker. 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// ASan activation/deactivation logic. 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "asan_activation.h" 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "asan_allocator.h" 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "asan_flags.h" 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "asan_internal.h" 1986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "asan_poisoning.h" 2086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "asan_stack.h" 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_flags.h" 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __asan { 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic struct AsanDeactivatedFlags { 2686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AllocatorOptions allocator_options; 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int malloc_context_size; 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines bool poison_heap; 2986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool coverage; 3086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *coverage_dir; 3186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void RegisterActivationFlags(FlagParser *parser, Flags *f, CommonFlags *cf) { 3386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_ACTIVATION_FLAG(Type, Name) \ 3486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RegisterFlag(parser, #Name, "", &f->Name); 3586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_ACTIVATION_FLAG(Type, Name) \ 3686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RegisterFlag(parser, #Name, "", &cf->Name); 3786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "asan_activation_flags.inc" 3886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#undef ASAN_ACTIVATION_FLAG 3986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#undef COMMON_ACTIVATION_FLAG 4086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 41799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar RegisterIncludeFlags(parser, cf); 4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 4486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void OverrideFromActivationFlags() { 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Flags f; 4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CommonFlags cf; 4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines FlagParser parser; 4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RegisterActivationFlags(&parser, &f, &cf); 4986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar cf.SetDefaults(); 5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Copy the current activation flags. 5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.CopyTo(&f, &cf); 5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.malloc_context_size = malloc_context_size; 5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines f.poison_heap = poison_heap; 5586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.coverage = coverage; 5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.coverage_dir = coverage_dir; 5786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.verbosity = Verbosity(); 5886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.help = false; // this is activation-specific help 5986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Check if activation flags need to be overriden. 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) { 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parser.ParseString(env); 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar InitializeCommonFlags(&cf); 6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity()) ReportUnrecognizedFlags(); 6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (cf.help) parser.PrintFlagDescriptions(); 7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.SetFrom(&f, &cf); 7286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines malloc_context_size = cf.malloc_context_size; 7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines poison_heap = f.poison_heap; 7486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines coverage = cf.coverage; 7586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines coverage_dir = cf.coverage_dir; 7686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void Print() { 7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report( 8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "quarantine_size_mb %d, max_redzone %d, poison_heap %d, " 8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "malloc_context_size %d, alloc_dealloc_mismatch %d, " 8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "allocator_may_return_null %d, coverage %d, coverage_dir %s\n", 8386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.quarantine_size_mb, allocator_options.max_redzone, 8486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines poison_heap, malloc_context_size, 8586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.alloc_dealloc_mismatch, 8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.may_return_null, coverage, coverage_dir); 8786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} asan_deactivated_flags; 892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool asan_is_deactivated; 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid AsanDeactivate() { 9386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(!asan_is_deactivated); 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Deactivating ASan\n"); 9586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Stash runtime state. 9786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines GetAllocatorOptions(&asan_deactivated_flags.allocator_options); 9886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.malloc_context_size = GetMallocContextSize(); 9986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.poison_heap = CanPoisonMemory(); 10086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage = common_flags()->coverage; 10186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir; 10286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Deactivate the runtime. 10486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetCanPoisonMemory(false); 10586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetMallocContextSize(1); 10686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeCoverage(false, nullptr); 10786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AllocatorOptions disabled = asan_deactivated_flags.allocator_options; 10986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.quarantine_size_mb = 0; 11086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. 11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.max_redzone = 16; 11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.alloc_dealloc_mismatch = false; 11386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.may_return_null = true; 11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeAllocator(disabled); 1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_is_deactivated = true; 1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanActivate() { 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!asan_is_deactivated) return; 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Activating ASan\n"); 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 123799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar UpdateProcessName(); 124799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 12586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.OverrideFromActivationFlags(); 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 12786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetCanPoisonMemory(asan_deactivated_flags.poison_heap); 12886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetMallocContextSize(asan_deactivated_flags.malloc_context_size); 12986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeCoverage(asan_deactivated_flags.coverage, 13086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage_dir); 13186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeAllocator(asan_deactivated_flags.allocator_options); 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_is_deactivated = false; 13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity()) { 13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report("Activated with flags:\n"); 13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.Print(); 13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // namespace __asan 141