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 4186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RegisterIncludeFlag(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 5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Copy the current activation flags. 5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.CopyTo(&f, &cf); 5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.malloc_context_size = malloc_context_size; 5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines f.poison_heap = poison_heap; 5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.coverage = coverage; 5586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.coverage_dir = coverage_dir; 5686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.verbosity = Verbosity(); 5786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines cf.help = false; // this is activation-specific help 5886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 5986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Check if activation flags need to be overriden. 6086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) { 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parser.ParseString(env); 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Override from getprop asan.options. 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char buf[100]; 6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines GetExtraActivationFlags(buf, sizeof(buf)); 6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parser.ParseString(buf); 6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetVerbosity(cf.verbosity); 7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity()) ReportUnrecognizedFlags(); 7286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (cf.help) parser.PrintFlagDescriptions(); 7486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 7586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.SetFrom(&f, &cf); 7686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines malloc_context_size = cf.malloc_context_size; 7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines poison_heap = f.poison_heap; 7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines coverage = cf.coverage; 7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines coverage_dir = cf.coverage_dir; 8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void Print() { 8386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report( 8486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "quarantine_size_mb %d, max_redzone %d, poison_heap %d, " 8586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "malloc_context_size %d, alloc_dealloc_mismatch %d, " 8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "allocator_may_return_null %d, coverage %d, coverage_dir %s\n", 8786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.quarantine_size_mb, allocator_options.max_redzone, 8886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines poison_heap, malloc_context_size, 8986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.alloc_dealloc_mismatch, 9086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines allocator_options.may_return_null, coverage, coverage_dir); 9186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} asan_deactivated_flags; 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic bool asan_is_deactivated; 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid AsanDeactivate() { 9786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(!asan_is_deactivated); 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Deactivating ASan\n"); 9986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Stash runtime state. 10186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines GetAllocatorOptions(&asan_deactivated_flags.allocator_options); 10286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.malloc_context_size = GetMallocContextSize(); 10386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.poison_heap = CanPoisonMemory(); 10486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage = common_flags()->coverage; 10586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir; 10686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Deactivate the runtime. 10886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetCanPoisonMemory(false); 10986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetMallocContextSize(1); 11086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeCoverage(false, nullptr); 11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AllocatorOptions disabled = asan_deactivated_flags.allocator_options; 11386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.quarantine_size_mb = 0; 11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. 11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.max_redzone = 16; 11686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.alloc_dealloc_mismatch = false; 11786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines disabled.may_return_null = true; 11886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeAllocator(disabled); 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_is_deactivated = true; 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanActivate() { 1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!asan_is_deactivated) return; 1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "Activating ASan\n"); 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 12786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.OverrideFromActivationFlags(); 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 12986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetCanPoisonMemory(asan_deactivated_flags.poison_heap); 13086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetMallocContextSize(asan_deactivated_flags.malloc_context_size); 13186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeCoverage(asan_deactivated_flags.coverage, 13286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.coverage_dir); 13386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ReInitializeAllocator(asan_deactivated_flags.allocator_options); 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_is_deactivated = false; 13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity()) { 13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report("Activated with flags:\n"); 13886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines asan_deactivated_flags.Print(); 13986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // namespace __asan 143