forked from OSchip/llvm-project
[ASan] Restrict the set of flags overriden at activation.
Summary: Change the way ASan flag parsing is performed at activation: instead of overwriting all ASan and common flags from the activation string, ASan will now only override a handful of whitelisted flags. This is a first step towards making runtime flags immutable after initialization. I plan to re-factor the activation stragegy to the following one: - Parse commandline flags. Override the defaults from compile definition, env var, etc. Flags are immutable at this point. - Initiailize the runtime from commandline flags. - If ASan needs to be started deactivated, stash the runtime state in "asan_deactivated_flags" and deactivate the runtime. - When ASan is activated, override "asan_deactivated_flags" with activation flags, and use it to re-activate the runtime. Test Plan: regression test suite Reviewers: eugenis, kcc Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6709 llvm-svn: 224601
This commit is contained in:
parent
583e9d29ad
commit
1b64854574
|
@ -29,6 +29,46 @@ static struct AsanDeactivatedFlags {
|
|||
bool poison_heap;
|
||||
bool alloc_dealloc_mismatch;
|
||||
bool allocator_may_return_null;
|
||||
|
||||
void CopyFrom(const Flags *f, const CommonFlags *cf) {
|
||||
quarantine_size = f->quarantine_size;
|
||||
max_redzone = f->max_redzone;
|
||||
malloc_context_size = cf->malloc_context_size;
|
||||
poison_heap = f->poison_heap;
|
||||
alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;
|
||||
allocator_may_return_null = cf->allocator_may_return_null;
|
||||
}
|
||||
|
||||
void OverrideFromActivationFlags() {
|
||||
Flags f;
|
||||
CommonFlags cf;
|
||||
|
||||
// Copy the current activation flags.
|
||||
f.quarantine_size = quarantine_size;
|
||||
f.max_redzone = max_redzone;
|
||||
cf.malloc_context_size = malloc_context_size;
|
||||
f.poison_heap = poison_heap;
|
||||
f.alloc_dealloc_mismatch = alloc_dealloc_mismatch;
|
||||
cf.allocator_may_return_null = allocator_may_return_null;
|
||||
|
||||
// Check if activation flags need to be overriden.
|
||||
// FIXME: Add diagnostic to check that activation flags string doesn't
|
||||
// contain any other flags.
|
||||
char buf[100];
|
||||
GetExtraActivationFlags(buf, sizeof(buf));
|
||||
ParseCommonFlagsFromString(&cf, buf);
|
||||
ParseFlagsFromString(&f, buf);
|
||||
|
||||
CopyFrom(&f, &cf);
|
||||
}
|
||||
|
||||
void Print() {
|
||||
Report("quarantine_size %d, max_redzone %d, poison_heap %d, "
|
||||
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
|
||||
"allocator_may_return_null %d\n",
|
||||
quarantine_size, max_redzone, poison_heap, malloc_context_size,
|
||||
alloc_dealloc_mismatch, allocator_may_return_null);
|
||||
}
|
||||
} asan_deactivated_flags;
|
||||
|
||||
static bool asan_is_deactivated;
|
||||
|
@ -36,16 +76,11 @@ static bool asan_is_deactivated;
|
|||
void AsanStartDeactivated() {
|
||||
VReport(1, "Deactivating ASan\n");
|
||||
// Save flag values.
|
||||
asan_deactivated_flags.quarantine_size = flags()->quarantine_size;
|
||||
asan_deactivated_flags.max_redzone = flags()->max_redzone;
|
||||
asan_deactivated_flags.poison_heap = flags()->poison_heap;
|
||||
asan_deactivated_flags.malloc_context_size =
|
||||
common_flags()->malloc_context_size;
|
||||
asan_deactivated_flags.alloc_dealloc_mismatch =
|
||||
flags()->alloc_dealloc_mismatch;
|
||||
asan_deactivated_flags.allocator_may_return_null =
|
||||
common_flags()->allocator_may_return_null;
|
||||
asan_deactivated_flags.CopyFrom(flags(), common_flags());
|
||||
|
||||
// FIXME: Don't overwrite commandline flags. Instead, make the flags store
|
||||
// the original values calculated during flag parsing, and re-initialize
|
||||
// the necessary runtime objects.
|
||||
flags()->quarantine_size = 0;
|
||||
flags()->max_redzone = 16;
|
||||
flags()->poison_heap = false;
|
||||
|
@ -60,35 +95,24 @@ void AsanActivate() {
|
|||
if (!asan_is_deactivated) return;
|
||||
VReport(1, "Activating ASan\n");
|
||||
|
||||
asan_deactivated_flags.OverrideFromActivationFlags();
|
||||
|
||||
// Restore flag values.
|
||||
// FIXME: this is not atomic, and there may be other threads alive.
|
||||
flags()->max_redzone = asan_deactivated_flags.max_redzone;
|
||||
flags()->alloc_dealloc_mismatch =
|
||||
asan_deactivated_flags.alloc_dealloc_mismatch;
|
||||
|
||||
// FIXME: Avoid modifying global common_flags() and flags() and restrict the
|
||||
// set of supported flags that can be provided in activation.
|
||||
char buf[100];
|
||||
GetExtraActivationFlags(buf, sizeof(buf));
|
||||
ParseCommonFlagsFromString(common_flags(), buf);
|
||||
ParseFlagsFromString(flags(), buf);
|
||||
if (buf[0] != '\0')
|
||||
VReport(1, "Extra activation flags: %s\n", buf);
|
||||
|
||||
SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
|
||||
SetMallocContextSize(asan_deactivated_flags.malloc_context_size);
|
||||
ReInitializeAllocator(asan_deactivated_flags.allocator_may_return_null,
|
||||
asan_deactivated_flags.quarantine_size);
|
||||
|
||||
asan_is_deactivated = false;
|
||||
VReport(1, "quarantine_size %d, max_redzone %d, poison_heap %d, "
|
||||
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
|
||||
"allocator_may_return_null %d\n",
|
||||
asan_deactivated_flags.quarantine_size, flags()->max_redzone,
|
||||
asan_deactivated_flags.poison_heap,
|
||||
asan_deactivated_flags.malloc_context_size,
|
||||
flags()->alloc_dealloc_mismatch,
|
||||
asan_deactivated_flags.allocator_may_return_null);
|
||||
if (common_flags()->verbosity) {
|
||||
Report("Activated with flags:\n");
|
||||
asan_deactivated_flags.Print();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace __asan
|
||||
|
|
Loading…
Reference in New Issue