diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2019-02-15 18:38:14 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2019-02-15 18:38:14 +0000 |
commit | 8f60425d39240ec5e4677d5378d2d7ca5b8a4269 (patch) | |
tree | efc59317b8cba3ae422ddae3c792a73542ecaca8 /lib/hwasan | |
parent | f7986b4647ca061257cf9fa9b456d64a2dd9e7d2 (diff) | |
download | compiler-rt-8f60425d39240ec5e4677d5378d2d7ca5b8a4269.tar.gz |
Runtime flags for malloc bisection.
Reviewers: kcc, pcc
Subscribers: kubamracek, mgorny, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58162
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@354156 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/hwasan')
-rw-r--r-- | lib/hwasan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/hwasan/hwasan_allocator.cc | 5 | ||||
-rw-r--r-- | lib/hwasan/hwasan_flags.inc | 13 | ||||
-rw-r--r-- | lib/hwasan/hwasan_malloc_bisect.h | 50 |
4 files changed, 67 insertions, 2 deletions
diff --git a/lib/hwasan/CMakeLists.txt b/lib/hwasan/CMakeLists.txt index 20ab94dc0..71db2d5a2 100644 --- a/lib/hwasan/CMakeLists.txt +++ b/lib/hwasan/CMakeLists.txt @@ -24,6 +24,7 @@ set(HWASAN_RTL_HEADERS hwasan_flags.h hwasan_flags.inc hwasan_interface_internal.h + hwasan_malloc_bisect.h hwasan_mapping.h hwasan_poisoning.h hwasan_report.h diff --git a/lib/hwasan/hwasan_allocator.cc b/lib/hwasan/hwasan_allocator.cc index 4a4de3e45..09f1ab94e 100644 --- a/lib/hwasan/hwasan_allocator.cc +++ b/lib/hwasan/hwasan_allocator.cc @@ -17,6 +17,7 @@ #include "hwasan.h" #include "hwasan_allocator.h" #include "hwasan_mapping.h" +#include "hwasan_malloc_bisect.h" #include "hwasan_thread.h" #include "hwasan_report.h" @@ -181,7 +182,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, // retag to 0. if ((flags()->tag_in_malloc || flags()->tag_in_free) && atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) { - tag_t tag = flags()->tag_in_malloc + tag_t tag = flags()->tag_in_malloc && malloc_bisect(stack, orig_size) ? (t ? t->GenerateRandomTag() : kFallbackAllocTag) : 0; user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, tag); @@ -247,7 +248,7 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { Min(TaggedSize(orig_size), (uptr)flags()->max_free_fill_size); internal_memset(aligned_ptr, flags()->free_fill_byte, fill_size); } - if (flags()->tag_in_free && + if (flags()->tag_in_free && malloc_bisect(stack, 0) && atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) TagMemoryAligned(reinterpret_cast<uptr>(aligned_ptr), TaggedSize(orig_size), t ? t->GenerateRandomTag() : kFallbackFreeTag); diff --git a/lib/hwasan/hwasan_flags.inc b/lib/hwasan/hwasan_flags.inc index f0cf151a4..01fdad87a 100644 --- a/lib/hwasan/hwasan_flags.inc +++ b/lib/hwasan/hwasan_flags.inc @@ -85,3 +85,16 @@ HWASAN_FLAG(int, stack_history_size, 1024, "The number of stack frames remembered per thread. " "Affects the quality of stack-related reports, but not the ability " "to find bugs.") + +// Malloc / free bisection. Only tag malloc and free calls when a hash of +// allocation size and stack trace is between malloc_bisect_left and +// malloc_bisect_right (both inclusive). [0, 0] range is special and disables +// bisection (i.e. everything is tagged). Once the range is narrowed down +// enough, use malloc_bisect_dump to see interesting allocations. +HWASAN_FLAG(uptr, malloc_bisect_left, 0, + "Left bound of malloc bisection, inclusive.") +HWASAN_FLAG(uptr, malloc_bisect_right, 0, + "Right bound of malloc bisection, inclusive.") +HWASAN_FLAG(bool, malloc_bisect_dump, false, + "Print all allocations within [malloc_bisect_left, " + "malloc_bisect_right] range ") diff --git a/lib/hwasan/hwasan_malloc_bisect.h b/lib/hwasan/hwasan_malloc_bisect.h new file mode 100644 index 000000000..eaf124aab --- /dev/null +++ b/lib/hwasan/hwasan_malloc_bisect.h @@ -0,0 +1,50 @@ +//===-- hwasan_malloc_bisect.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_hash.h" +#include "hwasan.h" + +namespace __hwasan { + +static u32 malloc_hash(StackTrace *stack, uptr orig_size) { + uptr len = Min(stack->size, (unsigned)7); + MurMur2HashBuilder H(len); + H.add(orig_size); + // Start with frame #1 to skip __sanitizer_malloc frame, which is + // (a) almost always the same (well, could be operator new or new[]) + // (b) can change hashes when compiler-rt is rebuilt, invalidating previous + // bisection results. + // Because of ASLR, use only offset inside the page. + for (uptr i = 1; i < len; ++i) H.add(((u32)stack->trace[i]) & 0xFFF); + return H.get(); +} + +static INLINE bool malloc_bisect(StackTrace *stack, uptr orig_size) { + uptr left = flags()->malloc_bisect_left; + uptr right = flags()->malloc_bisect_right; + if (LIKELY(left == 0 && right == 0)) + return true; + if (!stack) + return true; + // Allow malloc_bisect_right > (u32)(-1) to avoid spelling the latter in + // decimal. + uptr h = (uptr)malloc_hash(stack, orig_size); + if (h < left || h > right) + return false; + if (flags()->malloc_bisect_dump) { + Printf("[alloc] %u %zu\n", h, orig_size); + stack->Print(); + } + return true; +} + +} // namespace __hwasan |