diff options
Diffstat (limited to 'contrib/compiler-rt/lib/hwasan/hwasan_thread.cc')
-rw-r--r-- | contrib/compiler-rt/lib/hwasan/hwasan_thread.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/contrib/compiler-rt/lib/hwasan/hwasan_thread.cc b/contrib/compiler-rt/lib/hwasan/hwasan_thread.cc index d6551ffc6fdc..b50c0fc76be4 100644 --- a/contrib/compiler-rt/lib/hwasan/hwasan_thread.cc +++ b/contrib/compiler-rt/lib/hwasan/hwasan_thread.cc @@ -1,5 +1,6 @@ #include "hwasan.h" +#include "hwasan_mapping.h" #include "hwasan_thread.h" #include "hwasan_poisoning.h" #include "hwasan_interface_internal.h" @@ -8,6 +9,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 +30,7 @@ HwasanThread *HwasanThread::Create(thread_callback_t start_routine, thread->start_routine_ = start_routine; thread->arg_ = arg; thread->destructor_iterations_ = GetPthreadDestructorIterations(); + thread->random_state_ = flags()->random_tags ? RandomSeed() : 0; return thread; } @@ -72,4 +87,28 @@ thread_return_t HwasanThread::ThreadStart() { 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 (flags()->random_tags) { + if (!random_buffer_) + random_buffer_ = random_state_ = xorshift(random_state_); + CHECK(random_buffer_); + tag = random_buffer_ & 0xFF; + random_buffer_ >>= 8; + } else { + tag = random_state_ = (random_state_ + 1) & 0xFF; + } + } while (!tag); + return tag; +} + } // namespace __hwasan |