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