[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