From b430f6e17a2734013ec01da56072d789b9412036 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 22 Dec 2014 21:46:10 +0000 Subject: [PATCH] [Sanitizer] Make CommonFlags immutable after initialization. Summary: Protect CommonFlags singleton by adding const qualifier to common_flags() accessor. The only ways to modify the flags are SetCommonFlagsDefaults(), ParseCommonFlagsFromString() and OverrideCommonFlags() functions, which are only supposed to be called during initialization. Test Plan: regression test suite Reviewers: kcc, eugenis, glider Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6741 llvm-svn: 224736 --- compiler-rt/lib/asan/asan_flags.cc | 20 +++++++++++--------- compiler-rt/lib/lsan/lsan_common.cc | 9 +++++---- compiler-rt/lib/msan/msan.cc | 17 ++++++++++------- compiler-rt/lib/sanitizer_common/sanitizer_flags.h | 12 +++++++++++- compiler-rt/lib/tsan/dd/dd_rtl.cc | 9 ++++++--- compiler-rt/lib/tsan/rtl/tsan_flags.cc | 18 +++++++++++------- compiler-rt/lib/ubsan/ubsan_flags.cc | 5 +++-- 7 files changed, 57 insertions(+), 33 deletions(-) diff --git a/compiler-rt/lib/asan/asan_flags.cc b/compiler-rt/lib/asan/asan_flags.cc index 4099de2..7db1f02 100644 --- a/compiler-rt/lib/asan/asan_flags.cc +++ b/compiler-rt/lib/asan/asan_flags.cc @@ -172,13 +172,15 @@ void ParseFlagsFromString(Flags *f, const char *str) { } void InitializeFlags(Flags *f) { - CommonFlags *cf = common_flags(); SetCommonFlagsDefaults(); - cf->detect_leaks = CAN_SANITIZE_LEAKS; - cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); - cf->malloc_context_size = kDefaultMallocContextSize; - cf->intercept_tls_get_addr = true; - cf->coverage = false; + { + CommonFlags cf = *common_flags(); + cf.detect_leaks = CAN_SANITIZE_LEAKS; + cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); + cf.malloc_context_size = kDefaultMallocContextSize; + cf.intercept_tls_get_addr = true; + OverrideCommonFlags(cf); + } internal_memset(f, 0, sizeof(*f)); f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; @@ -258,17 +260,17 @@ void InitializeFlags(Flags *f) { } // Flag validation: - if (!CAN_SANITIZE_LEAKS && cf->detect_leaks) { + if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) { Report("%s: detect_leaks is not supported on this platform.\n", SanitizerToolName); - cf->detect_leaks = false; + Die(); } // Make "strict_init_order" imply "check_initialization_order". // TODO(samsonov): Use a single runtime flag for an init-order checker. if (f->strict_init_order) { f->check_initialization_order = true; } - CHECK_LE((uptr)cf->malloc_context_size, kStackTraceMax); + CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax); CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log); CHECK_GE(f->redzone, 16); CHECK_GE(f->max_redzone, f->redzone); diff --git a/compiler-rt/lib/lsan/lsan_common.cc b/compiler-rt/lib/lsan/lsan_common.cc index 89fef77..3d4d8a6 100644 --- a/compiler-rt/lib/lsan/lsan_common.cc +++ b/compiler-rt/lib/lsan/lsan_common.cc @@ -74,12 +74,13 @@ static void InitializeFlags(bool standalone) { // Set defaults for common flags (only in standalone mode) and parse // them from LSAN_OPTIONS. - CommonFlags *cf = common_flags(); if (standalone) { SetCommonFlagsDefaults(); - cf->external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); - cf->malloc_context_size = 30; - cf->detect_leaks = true; + CommonFlags cf = *common_flags(); + cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH"); + cf.malloc_context_size = 30; + cf.detect_leaks = true; + OverrideCommonFlags(cf); } ParseCommonFlagsFromString(options); } diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index fb18296..33b856b 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -144,14 +144,17 @@ static void ParseFlagsFromString(Flags *f, const char *str) { } static void InitializeFlags(Flags *f, const char *options) { - CommonFlags *cf = common_flags(); SetCommonFlagsDefaults(); - cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); - cf->malloc_context_size = 20; - cf->handle_ioctl = true; - // FIXME: test and enable. - cf->check_printf = false; - cf->intercept_tls_get_addr = true; + { + CommonFlags cf = *common_flags(); + cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); + cf.malloc_context_size = 20; + cf.handle_ioctl = true; + // FIXME: test and enable. + cf.check_printf = false; + cf.intercept_tls_get_addr = true; + OverrideCommonFlags(cf); + } internal_memset(f, 0, sizeof(*f)); f->poison_heap_with_zeroes = false; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.h b/compiler-rt/lib/sanitizer_common/sanitizer_flags.h index 698fc9c..b9f2204 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.h @@ -71,7 +71,7 @@ struct CommonFlags { // Functions to get/set global CommonFlags shared by all sanitizer runtimes: extern CommonFlags common_flags_dont_use; -inline CommonFlags *common_flags() { +inline const CommonFlags *common_flags() { return &common_flags_dont_use; } @@ -82,6 +82,16 @@ inline void SetCommonFlagsDefaults() { inline void ParseCommonFlagsFromString(const char *str) { common_flags_dont_use.ParseFromString(str); } + +// This function can only be used to setup tool-specific overrides for +// CommonFlags defaults. Generally, it should only be used right after +// SetCommonFlagsDefaults(), but before ParseCommonFlagsFromString(), and +// only during the flags initialization (i.e. before they are used for +// the first time). +inline void OverrideCommonFlags(const CommonFlags &cf) { + common_flags_dont_use = cf; +} + void PrintFlagDescriptions(); } // namespace __sanitizer diff --git a/compiler-rt/lib/tsan/dd/dd_rtl.cc b/compiler-rt/lib/tsan/dd/dd_rtl.cc index cc8e5a0..3fd893d 100644 --- a/compiler-rt/lib/tsan/dd/dd_rtl.cc +++ b/compiler-rt/lib/tsan/dd/dd_rtl.cc @@ -70,10 +70,13 @@ void InitializeFlags(Flags *f, const char *env) { // Default values. f->second_deadlock_stack = false; - CommonFlags *cf = common_flags(); SetCommonFlagsDefaults(); - // Override some common flags defaults. - cf->allow_addr2line = true; + { + // Override some common flags defaults. + CommonFlags cf = *common_flags(); + cf.allow_addr2line = true; + OverrideCommonFlags(cf); + } // Override from command line. ParseFlag(env, &f->second_deadlock_stack, "second_deadlock_stack", ""); diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cc b/compiler-rt/lib/tsan/rtl/tsan_flags.cc index ec74a24..70fa180 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cc @@ -93,13 +93,16 @@ void InitializeFlags(Flags *f, const char *env) { // DDFlags f->second_deadlock_stack = false; - CommonFlags *cf = common_flags(); SetCommonFlagsDefaults(); - // Override some common flags defaults. - cf->allow_addr2line = true; - cf->detect_deadlocks = true; - cf->print_suppressions = false; - cf->stack_trace_format = " #%n %f %S %M"; + { + // Override some common flags defaults. + CommonFlags cf = *common_flags(); + cf.allow_addr2line = true; + cf.detect_deadlocks = true; + cf.print_suppressions = false; + cf.stack_trace_format = " #%n %f %S %M"; + OverrideCommonFlags(cf); + } // Let a frontend override. ParseFlags(f, __tsan_default_options()); @@ -115,7 +118,8 @@ void InitializeFlags(Flags *f, const char *env) { f->report_signal_unsafe = false; } - if (cf->help) PrintFlagDescriptions(); + if (common_flags()->help) + PrintFlagDescriptions(); if (f->history_size < 0 || f->history_size > 7) { Printf("ThreadSanitizer: incorrect value for history_size" diff --git a/compiler-rt/lib/ubsan/ubsan_flags.cc b/compiler-rt/lib/ubsan/ubsan_flags.cc index db0e29b..61e703c 100644 --- a/compiler-rt/lib/ubsan/ubsan_flags.cc +++ b/compiler-rt/lib/ubsan/ubsan_flags.cc @@ -22,9 +22,10 @@ static const char *MaybeCallUbsanDefaultOptions() { } void InitializeCommonFlags() { - CommonFlags *cf = common_flags(); SetCommonFlagsDefaults(); - cf->print_summary = false; + CommonFlags cf = *common_flags(); + cf.print_summary = false; + OverrideCommonFlags(cf); // Override from user-specified string. ParseCommonFlagsFromString(MaybeCallUbsanDefaultOptions()); // Override from environment variable. -- 2.7.4