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