[compiler-rt] r321761 - [hwasan] Add heap tag randomization.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 3 13:42:28 PST 2018
Author: eugenis
Date: Wed Jan 3 13:42:28 2018
New Revision: 321761
URL: http://llvm.org/viewvc/llvm-project?rev=321761&view=rev
Log:
[hwasan] Add heap tag randomization.
Summary:
Generate tags for heap allocations from a pseudo-random sequence
seeded with getrandom(), where available.
Reviewers: kcc, alekseyshl
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D41616
Modified:
compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.h
Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc?rev=321761&r1=321760&r2=321761&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc Wed Jan 3 13:42:28 2018
@@ -100,6 +100,9 @@ static AllocatorCache fallback_allocator
static SpinMutex fallback_mutex;
static atomic_uint8_t hwasan_allocator_tagging_enabled;
+static const tag_t kFallbackAllocTag = 0xBB;
+static const tag_t kFallbackFreeTag = 0xBC;
+
void HwasanAllocatorInit() {
atomic_store_relaxed(&hwasan_allocator_tagging_enabled,
!flags()->disable_allocator_tagging);
@@ -145,10 +148,11 @@ static void *HwasanAllocate(StackTrace *
if (zeroise)
internal_memset(allocated, 0, size);
- void *user_ptr = (flags()->tag_in_malloc &&
- atomic_load_relaxed(&hwasan_allocator_tagging_enabled))
- ? (void *)TagMemoryAligned((uptr)allocated, size, 0xBB)
- : allocated;
+ void *user_ptr = allocated;
+ if (flags()->tag_in_malloc &&
+ atomic_load_relaxed(&hwasan_allocator_tagging_enabled))
+ user_ptr = (void *)TagMemoryAligned(
+ (uptr)user_ptr, size, t ? t->GenerateRandomTag() : kFallbackAllocTag);
HWASAN_MALLOC_HOOK(user_ptr, size);
return user_ptr;
@@ -166,10 +170,11 @@ void HwasanDeallocate(StackTrace *stack,
meta->free_context_id = StackDepotPut(*stack);
// This memory will not be reused by anyone else, so we are free to keep it
// poisoned.
+ HwasanThread *t = GetCurrentThread();
if (flags()->tag_in_free &&
atomic_load_relaxed(&hwasan_allocator_tagging_enabled))
- TagMemoryAligned((uptr)p, size, 0xBC);
- HwasanThread *t = GetCurrentThread();
+ TagMemoryAligned((uptr)p, size,
+ t ? t->GenerateRandomTag() : kFallbackFreeTag);
if (t) {
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
allocator.Deallocate(cache, p);
@@ -195,8 +200,12 @@ void *HwasanReallocate(StackTrace *stack
meta->requested_size = new_size;
if (!atomic_load_relaxed(&hwasan_allocator_tagging_enabled))
return user_old_p;
- if (flags()->retag_in_realloc)
- return (void *)TagMemoryAligned((uptr)old_p, new_size, 0xCC);
+ if (flags()->retag_in_realloc) {
+ HwasanThread *t = GetCurrentThread();
+ return (void *)TagMemoryAligned(
+ (uptr)old_p, new_size,
+ t ? t->GenerateRandomTag() : kFallbackAllocTag);
+ }
if (new_size > old_size) {
tag_t tag = GetTagFromPointer((uptr)user_old_p);
TagMemoryAligned((uptr)old_p + old_size, new_size - old_size, tag);
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=321761&r1=321760&r2=321761&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Wed Jan 3 13:42:28 2018
@@ -8,6 +8,19 @@
namespace __hwasan {
+static u32 RandomSeed() {
+ u32 seed;
+ do {
+ if (UNLIKELY(!GetRandom(reinterpret_cast<void *>(&seed), sizeof(seed),
+ /*blocking=*/false))) {
+ seed = static_cast<u32>(
+ (NanoTime() >> 12) ^
+ (reinterpret_cast<uptr>(__builtin_frame_address(0)) >> 4));
+ }
+ } while (!seed);
+ return seed;
+}
+
HwasanThread *HwasanThread::Create(thread_callback_t start_routine,
void *arg) {
uptr PageSize = GetPageSizeCached();
@@ -16,6 +29,7 @@ HwasanThread *HwasanThread::Create(threa
thread->start_routine_ = start_routine;
thread->arg_ = arg;
thread->destructor_iterations_ = GetPthreadDestructorIterations();
+ thread->random_state_ = RandomSeed();
return thread;
}
@@ -72,4 +86,24 @@ thread_return_t HwasanThread::ThreadStar
return res;
}
+static u32 xorshift(u32 state) {
+ state ^= state << 13;
+ state ^= state >> 17;
+ state ^= state << 5;
+ return state;
+}
+
+// Generate a (pseudo-)random non-zero tag.
+tag_t HwasanThread::GenerateRandomTag() {
+ tag_t tag;
+ do {
+ if (!random_buffer_)
+ random_buffer_ = random_state_ = xorshift(random_state_);
+ CHECK(random_buffer_);
+ tag = random_buffer_ & 0xFF;
+ random_buffer_ >>= 8;
+ } while (!tag);
+ return tag;
+}
+
} // namespace __hwasan
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=321761&r1=321760&r2=321761&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Wed Jan 3 13:42:28 2018
@@ -52,6 +52,8 @@ class HwasanThread {
HwasanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
+ tag_t GenerateRandomTag();
+
int destructor_iterations_;
private:
@@ -70,6 +72,9 @@ class HwasanThread {
unsigned in_symbolizer_;
unsigned in_interceptor_scope_;
+ u32 random_state_;
+ u32 random_buffer_;
+
HwasanThreadLocalMallocStorage malloc_storage_;
};
More information about the llvm-commits
mailing list