Index: lib/asan/asan_activation.cc =================================================================== --- lib/asan/asan_activation.cc +++ lib/asan/asan_activation.cc @@ -23,7 +23,7 @@ namespace __asan { static struct AsanDeactivatedFlags { - int quarantine_size; + uptr quarantine_size; int max_redzone; int malloc_context_size; bool poison_heap; @@ -60,12 +60,6 @@ if (!asan_is_deactivated) return; VReport(1, "Activating ASan\n"); - // 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]; @@ -77,8 +71,13 @@ 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); + + AllocatorOptions allocator_options = { + asan_deactivated_flags.allocator_may_return_null, + asan_deactivated_flags.quarantine_size, + asan_deactivated_flags.alloc_dealloc_mismatch, flags()->redzone, + asan_deactivated_flags.max_redzone}; + ReInitializeAllocator(allocator_options); asan_is_deactivated = false; VReport(1, "quarantine_size %d, max_redzone %d, poison_heap %d, " Index: lib/asan/asan_allocator.h =================================================================== --- lib/asan/asan_allocator.h +++ lib/asan/asan_allocator.h @@ -31,8 +31,16 @@ static const uptr kNumberOfSizeClasses = 255; struct AsanChunk; -void InitializeAllocator(bool may_return_null, uptr quarantine_size); -void ReInitializeAllocator(bool may_return_null, uptr quarantine_size); +struct AllocatorOptions { + bool may_return_null; + uptr quarantine_size; + bool alloc_dealloc_mismatch; + int min_redzone; + int max_redzone; +}; + +void InitializeAllocator(const AllocatorOptions &options); +void ReInitializeAllocator(const AllocatorOptions &options); class AsanChunkView { public: Index: lib/asan/asan_allocator.cc =================================================================== --- lib/asan/asan_allocator.cc +++ lib/asan/asan_allocator.cc @@ -217,19 +217,41 @@ AllocatorCache fallback_allocator_cache; QuarantineCache fallback_quarantine_cache; + // ------------------- Options -------------------------- + atomic_uint8_t alloc_dealloc_mismatch; + atomic_uint32_t min_redzone; + atomic_uint32_t max_redzone; + + // ------------------- Initialization ------------------------ explicit Allocator(LinkerInitialized) : quarantine(LINKER_INITIALIZED), fallback_quarantine_cache(LINKER_INITIALIZED) {} - // ------------------- Initialization ------------------------ - void Initialize(bool may_return_null, uptr quarantine_size) { - allocator.Init(may_return_null); - quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine); + void CheckOptions(const AllocatorOptions &options) const { + CHECK_GE(options.min_redzone, 16); + CHECK_GE(options.max_redzone, options.min_redzone); + CHECK_LE(options.max_redzone, 2048); + CHECK(IsPowerOfTwo(options.min_redzone)); + CHECK(IsPowerOfTwo(options.max_redzone)); + } + + void SharedInitCode(const AllocatorOptions &options) { + CheckOptions(options); + quarantine.Init(options.quarantine_size, kMaxThreadLocalQuarantine); + atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch, + memory_order_release); + atomic_store(&min_redzone, options.min_redzone, memory_order_release); + atomic_store(&max_redzone, options.max_redzone, memory_order_release); } - void ReInitialize(bool may_return_null, uptr quarantine_size) { - allocator.SetMayReturnNull(may_return_null); - quarantine.Init(quarantine_size, kMaxThreadLocalQuarantine); + void Initialize(const AllocatorOptions &options) { + allocator.Init(options.may_return_null); + SharedInitCode(options); + } + + void ReInitialize(const AllocatorOptions &options) { + allocator.SetMayReturnNull(options.may_return_null); + SharedInitCode(options); } // -------------------- Helper methods. ------------------------- @@ -242,8 +264,9 @@ user_requested_size <= (1 << 14) - 256 ? 4 : user_requested_size <= (1 << 15) - 512 ? 5 : user_requested_size <= (1 << 16) - 1024 ? 6 : 7; - return Min(Max(rz_log, RZSize2Log(flags()->redzone)), - RZSize2Log(flags()->max_redzone)); + u32 min_rz = atomic_load(&min_redzone, memory_order_acquire); + u32 max_rz = atomic_load(&max_redzone, memory_order_acquire); + return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz)); } // We have an address between two chunks, and we want to report just one. @@ -419,9 +442,12 @@ AllocType alloc_type) { CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE); - if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch) - ReportAllocTypeMismatch((uptr)ptr, stack, - (AllocType)m->alloc_type, (AllocType)alloc_type); + if (m->alloc_type != alloc_type) { + if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) { + ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type, + (AllocType)alloc_type); + } + } CHECK_GE(m->alloc_tid, 0); if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area. @@ -619,12 +645,12 @@ return GetStackTraceFromId(chunk_->free_context_id); } -void InitializeAllocator(bool may_return_null, uptr quarantine_size) { - instance.Initialize(may_return_null, quarantine_size); +void InitializeAllocator(const AllocatorOptions &options) { + instance.Initialize(options); } -void ReInitializeAllocator(bool may_return_null, uptr quarantine_size) { - instance.ReInitialize(may_return_null, quarantine_size); +void ReInitializeAllocator(const AllocatorOptions &options) { + instance.ReInitialize(options); } AsanChunkView FindHeapChunkByAddress(uptr addr) { Index: lib/asan/asan_flags.cc =================================================================== --- lib/asan/asan_flags.cc +++ lib/asan/asan_flags.cc @@ -50,11 +50,6 @@ "Requirement: redzone >= 16, is a power of two."); ParseFlag(str, &f->max_redzone, "max_redzone", "Maximal size (in bytes) of redzones around heap objects."); - CHECK_GE(f->redzone, 16); - CHECK_GE(f->max_redzone, f->redzone); - CHECK_LE(f->max_redzone, 2048); - CHECK(IsPowerOfTwo(f->redzone)); - CHECK(IsPowerOfTwo(f->max_redzone)); ParseFlag(str, &f->debug, "debug", "If set, prints some debugging information and does additional checks."); Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -391,8 +391,10 @@ AsanTSDInit(PlatformTSDDtor); InstallDeadlySignalHandlers(AsanOnSIGSEGV); - InitializeAllocator(common_flags()->allocator_may_return_null, - flags()->quarantine_size); + AllocatorOptions allocator_options = { + common_flags()->allocator_may_return_null, (uptr)flags()->quarantine_size, + flags()->alloc_dealloc_mismatch, flags()->redzone, flags()->max_redzone}; + InitializeAllocator(allocator_options); MaybeStartBackgroudThread();