aboutsummaryrefslogtreecommitdiff
path: root/lib/hwasan/hwasan_thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hwasan/hwasan_thread.cc')
-rw-r--r--lib/hwasan/hwasan_thread.cc39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/hwasan/hwasan_thread.cc b/lib/hwasan/hwasan_thread.cc
index d6551ffc6fdc..b50c0fc76be4 100644
--- a/lib/hwasan/hwasan_thread.cc
+++ b/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