hwasan_thread.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "hwasan_thread.h"
  2. #include "hwasan.h"
  3. #include "hwasan_interface_internal.h"
  4. #include "hwasan_mapping.h"
  5. #include "hwasan_poisoning.h"
  6. #include "sanitizer_common/sanitizer_atomic.h"
  7. #include "sanitizer_common/sanitizer_file.h"
  8. #include "sanitizer_common/sanitizer_placement_new.h"
  9. #include "sanitizer_common/sanitizer_tls_get_addr.h"
  10. namespace __hwasan {
  11. static u32 RandomSeed() {
  12. u32 seed;
  13. do {
  14. if (UNLIKELY(!GetRandom(reinterpret_cast<void *>(&seed), sizeof(seed),
  15. /*blocking=*/false))) {
  16. seed = static_cast<u32>(
  17. (NanoTime() >> 12) ^
  18. (reinterpret_cast<uptr>(__builtin_frame_address(0)) >> 4));
  19. }
  20. } while (!seed);
  21. return seed;
  22. }
  23. void Thread::InitRandomState() {
  24. random_state_ = flags()->random_tags ? RandomSeed() : unique_id_;
  25. random_state_inited_ = true;
  26. // Push a random number of zeros onto the ring buffer so that the first stack
  27. // tag base will be random.
  28. for (tag_t i = 0, e = GenerateRandomTag(); i != e; ++i)
  29. stack_allocations_->push(0);
  30. }
  31. void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size,
  32. const InitState *state) {
  33. CHECK_EQ(0, unique_id_); // try to catch bad stack reuse
  34. CHECK_EQ(0, stack_top_);
  35. CHECK_EQ(0, stack_bottom_);
  36. static atomic_uint64_t unique_id;
  37. unique_id_ = atomic_fetch_add(&unique_id, 1, memory_order_relaxed);
  38. if (auto sz = flags()->heap_history_size)
  39. heap_allocations_ = HeapAllocationsRingBuffer::New(sz);
  40. #if !SANITIZER_FUCHSIA
  41. // Do not initialize the stack ring buffer just yet on Fuchsia. Threads will
  42. // be initialized before we enter the thread itself, so we will instead call
  43. // this later.
  44. InitStackRingBuffer(stack_buffer_start, stack_buffer_size);
  45. #endif
  46. InitStackAndTls(state);
  47. }
  48. void Thread::InitStackRingBuffer(uptr stack_buffer_start,
  49. uptr stack_buffer_size) {
  50. HwasanTSDThreadInit(); // Only needed with interceptors.
  51. uptr *ThreadLong = GetCurrentThreadLongPtr();
  52. // The following implicitly sets (this) as the current thread.
  53. stack_allocations_ = new (ThreadLong)
  54. StackAllocationsRingBuffer((void *)stack_buffer_start, stack_buffer_size);
  55. // Check that it worked.
  56. CHECK_EQ(GetCurrentThread(), this);
  57. // ScopedTaggingDisable needs GetCurrentThread to be set up.
  58. ScopedTaggingDisabler disabler;
  59. if (stack_bottom_) {
  60. int local;
  61. CHECK(AddrIsInStack((uptr)&local));
  62. CHECK(MemIsApp(stack_bottom_));
  63. CHECK(MemIsApp(stack_top_ - 1));
  64. }
  65. if (flags()->verbose_threads) {
  66. if (IsMainThread()) {
  67. Printf("sizeof(Thread): %zd sizeof(HeapRB): %zd sizeof(StackRB): %zd\n",
  68. sizeof(Thread), heap_allocations_->SizeInBytes(),
  69. stack_allocations_->size() * sizeof(uptr));
  70. }
  71. Print("Creating : ");
  72. }
  73. }
  74. void Thread::ClearShadowForThreadStackAndTLS() {
  75. if (stack_top_ != stack_bottom_)
  76. TagMemory(stack_bottom_, stack_top_ - stack_bottom_, 0);
  77. if (tls_begin_ != tls_end_)
  78. TagMemory(tls_begin_, tls_end_ - tls_begin_, 0);
  79. }
  80. void Thread::Destroy() {
  81. if (flags()->verbose_threads)
  82. Print("Destroying: ");
  83. AllocatorSwallowThreadLocalCache(allocator_cache());
  84. ClearShadowForThreadStackAndTLS();
  85. if (heap_allocations_)
  86. heap_allocations_->Delete();
  87. DTLS_Destroy();
  88. // Unregister this as the current thread.
  89. // Instrumented code can not run on this thread from this point onwards, but
  90. // malloc/free can still be served. Glibc may call free() very late, after all
  91. // TSD destructors are done.
  92. CHECK_EQ(GetCurrentThread(), this);
  93. *GetCurrentThreadLongPtr() = 0;
  94. }
  95. void Thread::Print(const char *Prefix) {
  96. Printf("%sT%zd %p stack: [%p,%p) sz: %zd tls: [%p,%p)\n", Prefix, unique_id_,
  97. (void *)this, stack_bottom(), stack_top(),
  98. stack_top() - stack_bottom(), tls_begin(), tls_end());
  99. }
  100. static u32 xorshift(u32 state) {
  101. state ^= state << 13;
  102. state ^= state >> 17;
  103. state ^= state << 5;
  104. return state;
  105. }
  106. // Generate a (pseudo-)random non-zero tag.
  107. tag_t Thread::GenerateRandomTag(uptr num_bits) {
  108. DCHECK_GT(num_bits, 0);
  109. if (tagging_disabled_)
  110. return 0;
  111. tag_t tag;
  112. const uptr tag_mask = (1ULL << num_bits) - 1;
  113. do {
  114. if (flags()->random_tags) {
  115. if (!random_buffer_) {
  116. EnsureRandomStateInited();
  117. random_buffer_ = random_state_ = xorshift(random_state_);
  118. }
  119. CHECK(random_buffer_);
  120. tag = random_buffer_ & tag_mask;
  121. random_buffer_ >>= num_bits;
  122. } else {
  123. EnsureRandomStateInited();
  124. random_state_ += 1;
  125. tag = random_state_ & tag_mask;
  126. }
  127. } while (!tag);
  128. return tag;
  129. }
  130. } // namespace __hwasan