aboutsummaryrefslogtreecommitdiff
path: root/libsanitizer/hwasan
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-11-12 22:23:45 -0800
committerH.J. Lu <hjl.tools@gmail.com>2021-11-13 05:15:24 -0800
commit86289a4ff4768fab61f16372650fe85c37f9284e (patch)
tree4e2328cbff3a90cb8739f7e6fd95621d8aa16789 /libsanitizer/hwasan
parenta30a2e43e4a357919ecfa916451966f8e32b5176 (diff)
downloadgcc-86289a4ff4768fab61f16372650fe85c37f9284e.zip
gcc-86289a4ff4768fab61f16372650fe85c37f9284e.tar.gz
gcc-86289a4ff4768fab61f16372650fe85c37f9284e.tar.bz2
libsanitizer: Merge with upstream
Merged revision: 82bc6a094e85014f1891ef9407496f44af8fe442 with the fix for PR sanitizer/102911
Diffstat (limited to 'libsanitizer/hwasan')
-rw-r--r--libsanitizer/hwasan/hwasan.cpp2
-rw-r--r--libsanitizer/hwasan/hwasan_allocation_functions.cpp59
-rw-r--r--libsanitizer/hwasan/hwasan_exceptions.cpp4
-rw-r--r--libsanitizer/hwasan/hwasan_fuchsia.cpp2
-rw-r--r--libsanitizer/hwasan/hwasan_linux.cpp2
-rw-r--r--libsanitizer/hwasan/hwasan_thread.cpp22
-rw-r--r--libsanitizer/hwasan/hwasan_thread.h10
7 files changed, 47 insertions, 54 deletions
diff --git a/libsanitizer/hwasan/hwasan.cpp b/libsanitizer/hwasan/hwasan.cpp
index c286340..6f0ea64 100644
--- a/libsanitizer/hwasan/hwasan.cpp
+++ b/libsanitizer/hwasan/hwasan.cpp
@@ -345,7 +345,7 @@ __attribute__((constructor(0))) void __hwasan_init() {
// Needs to be called here because flags()->random_tags might not have been
// initialized when InitInstrumentation() was called.
- GetCurrentThread()->InitRandomState();
+ GetCurrentThread()->EnsureRandomStateInited();
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
// This may call libc -> needs initialized shadow.
diff --git a/libsanitizer/hwasan/hwasan_allocation_functions.cpp b/libsanitizer/hwasan/hwasan_allocation_functions.cpp
index 850daed..9cd82db 100644
--- a/libsanitizer/hwasan/hwasan_allocation_functions.cpp
+++ b/libsanitizer/hwasan/hwasan_allocation_functions.cpp
@@ -14,6 +14,7 @@
#include "hwasan.h"
#include "interception/interception.h"
+#include "sanitizer_common/sanitizer_allocator_dlsym.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
@@ -21,22 +22,9 @@
using namespace __hwasan;
-static uptr allocated_for_dlsym;
-static const uptr kDlsymAllocPoolSize = 1024;
-static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
-
-static bool IsInDlsymAllocPool(const void *ptr) {
- uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
- return off < sizeof(alloc_memory_for_dlsym);
-}
-
-static void *AllocateFromLocalPool(uptr size_in_bytes) {
- uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
- void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym];
- allocated_for_dlsym += size_in_words;
- CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
- return mem;
-}
+struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
+ static bool UseImpl() { return !hwasan_inited; }
+};
extern "C" {
@@ -83,17 +71,21 @@ void *__sanitizer_pvalloc(uptr size) {
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_free(void *ptr) {
- GET_MALLOC_STACK_TRACE;
- if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr)))
+ if (!ptr)
return;
+ if (DlsymAlloc::PointerIsMine(ptr))
+ return DlsymAlloc::Free(ptr);
+ GET_MALLOC_STACK_TRACE;
hwasan_free(ptr, &stack);
}
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_cfree(void *ptr) {
- GET_MALLOC_STACK_TRACE;
- if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr)))
+ if (!ptr)
return;
+ if (DlsymAlloc::PointerIsMine(ptr))
+ return DlsymAlloc::Free(ptr);
+ GET_MALLOC_STACK_TRACE;
hwasan_free(ptr, &stack);
}
@@ -119,29 +111,17 @@ void __sanitizer_malloc_stats(void) {
SANITIZER_INTERFACE_ATTRIBUTE
void *__sanitizer_calloc(uptr nmemb, uptr size) {
+ if (DlsymAlloc::Use())
+ return DlsymAlloc::Callocate(nmemb, size);
GET_MALLOC_STACK_TRACE;
- if (UNLIKELY(!hwasan_inited))
- // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
- return AllocateFromLocalPool(nmemb * size);
return hwasan_calloc(nmemb, size, &stack);
}
SANITIZER_INTERFACE_ATTRIBUTE
void *__sanitizer_realloc(void *ptr, uptr size) {
+ if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
+ return DlsymAlloc::Realloc(ptr, size);
GET_MALLOC_STACK_TRACE;
- if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
- uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
- uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
- void *new_ptr;
- if (UNLIKELY(!hwasan_inited)) {
- new_ptr = AllocateFromLocalPool(copy_size);
- } else {
- copy_size = size;
- new_ptr = hwasan_malloc(copy_size, &stack);
- }
- internal_memcpy(new_ptr, ptr, copy_size);
- return new_ptr;
- }
return hwasan_realloc(ptr, size, &stack);
}
@@ -153,12 +133,11 @@ void *__sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) {
SANITIZER_INTERFACE_ATTRIBUTE
void *__sanitizer_malloc(uptr size) {
- GET_MALLOC_STACK_TRACE;
if (UNLIKELY(!hwasan_init_is_running))
ENSURE_HWASAN_INITED();
- if (UNLIKELY(!hwasan_inited))
- // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
- return AllocateFromLocalPool(size);
+ if (DlsymAlloc::Use())
+ return DlsymAlloc::Allocate(size);
+ GET_MALLOC_STACK_TRACE;
return hwasan_malloc(size, &stack);
}
diff --git a/libsanitizer/hwasan/hwasan_exceptions.cpp b/libsanitizer/hwasan/hwasan_exceptions.cpp
index 169e787..6ed1da3 100644
--- a/libsanitizer/hwasan/hwasan_exceptions.cpp
+++ b/libsanitizer/hwasan/hwasan_exceptions.cpp
@@ -29,8 +29,8 @@ typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions,
// is statically linked and the sanitizer runtime and the program are linked
// against different unwinders. The _Unwind_Context data structure is opaque so
// it may be incompatible between unwinders.
-typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index);
-typedef _Unwind_Word GetCFAFn(_Unwind_Context* context);
+typedef uintptr_t GetGRFn(_Unwind_Context* context, int index);
+typedef uintptr_t GetCFAFn(_Unwind_Context* context);
extern "C" SANITIZER_INTERFACE_ATTRIBUTE _Unwind_Reason_Code
__hwasan_personality_wrapper(int version, _Unwind_Action actions,
diff --git a/libsanitizer/hwasan/hwasan_fuchsia.cpp b/libsanitizer/hwasan/hwasan_fuchsia.cpp
index f51e148..94e5c5f 100644
--- a/libsanitizer/hwasan/hwasan_fuchsia.cpp
+++ b/libsanitizer/hwasan/hwasan_fuchsia.cpp
@@ -130,7 +130,7 @@ static void ThreadCreateHook(void *hook, bool aborted) {
static void ThreadStartHook(void *hook, thrd_t self) {
Thread *thread = static_cast<Thread *>(hook);
FinishThreadInitialization(thread);
- thread->InitRandomState();
+ thread->EnsureRandomStateInited();
}
// This is the function that sets up the stack ring buffer and enables us to use
diff --git a/libsanitizer/hwasan/hwasan_linux.cpp b/libsanitizer/hwasan/hwasan_linux.cpp
index a86ec28..ba9e236 100644
--- a/libsanitizer/hwasan/hwasan_linux.cpp
+++ b/libsanitizer/hwasan/hwasan_linux.cpp
@@ -250,7 +250,7 @@ void InstallAtExitHandler() { atexit(HwasanAtExit); }
// ---------------------- TSD ---------------- {{{1
extern "C" void __hwasan_thread_enter() {
- hwasanThreadList().CreateCurrentThread()->InitRandomState();
+ hwasanThreadList().CreateCurrentThread()->EnsureRandomStateInited();
}
extern "C" void __hwasan_thread_exit() {
diff --git a/libsanitizer/hwasan/hwasan_thread.cpp b/libsanitizer/hwasan/hwasan_thread.cpp
index 5f05446..c776ae1 100644
--- a/libsanitizer/hwasan/hwasan_thread.cpp
+++ b/libsanitizer/hwasan/hwasan_thread.cpp
@@ -1,15 +1,15 @@
+#include "hwasan_thread.h"
+
#include "hwasan.h"
+#include "hwasan_interface_internal.h"
#include "hwasan_mapping.h"
-#include "hwasan_thread.h"
#include "hwasan_poisoning.h"
-#include "hwasan_interface_internal.h"
-
+#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_placement_new.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
-
namespace __hwasan {
static u32 RandomSeed() {
@@ -27,6 +27,7 @@ static u32 RandomSeed() {
void Thread::InitRandomState() {
random_state_ = flags()->random_tags ? RandomSeed() : unique_id_;
+ random_state_inited_ = true;
// Push a random number of zeros onto the ring buffer so that the first stack
// tag base will be random.
@@ -40,8 +41,9 @@ void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size,
CHECK_EQ(0, stack_top_);
CHECK_EQ(0, stack_bottom_);
- static u64 unique_id;
- unique_id_ = unique_id++;
+ static atomic_uint64_t unique_id;
+ unique_id_ = atomic_fetch_add(&unique_id, 1, memory_order_relaxed);
+
if (auto sz = flags()->heap_history_size)
heap_allocations_ = HeapAllocationsRingBuffer::New(sz);
@@ -123,17 +125,21 @@ static u32 xorshift(u32 state) {
// Generate a (pseudo-)random non-zero tag.
tag_t Thread::GenerateRandomTag(uptr num_bits) {
DCHECK_GT(num_bits, 0);
- if (tagging_disabled_) return 0;
+ if (tagging_disabled_)
+ return 0;
tag_t tag;
const uptr tag_mask = (1ULL << num_bits) - 1;
do {
if (flags()->random_tags) {
- if (!random_buffer_)
+ if (!random_buffer_) {
+ EnsureRandomStateInited();
random_buffer_ = random_state_ = xorshift(random_state_);
+ }
CHECK(random_buffer_);
tag = random_buffer_ & tag_mask;
random_buffer_ >>= num_bits;
} else {
+ EnsureRandomStateInited();
random_state_ += 1;
tag = random_state_ & tag_mask;
}
diff --git a/libsanitizer/hwasan/hwasan_thread.h b/libsanitizer/hwasan/hwasan_thread.h
index 9f20afe..3db7c1a 100644
--- a/libsanitizer/hwasan/hwasan_thread.h
+++ b/libsanitizer/hwasan/hwasan_thread.h
@@ -28,12 +28,17 @@ class Thread {
void Init(uptr stack_buffer_start, uptr stack_buffer_size,
const InitState *state = nullptr);
- void InitRandomState();
+
void InitStackAndTls(const InitState *state = nullptr);
// Must be called from the thread itself.
void InitStackRingBuffer(uptr stack_buffer_start, uptr stack_buffer_size);
+ inline void EnsureRandomStateInited() {
+ if (UNLIKELY(!random_state_inited_))
+ InitRandomState();
+ }
+
void Destroy();
uptr stack_top() { return stack_top_; }
@@ -70,6 +75,7 @@ class Thread {
// via mmap() and *must* be valid in zero-initialized state.
void ClearShadowForThreadStackAndTLS();
void Print(const char *prefix);
+ void InitRandomState();
uptr vfork_spill_;
uptr stack_top_;
uptr stack_bottom_;
@@ -89,6 +95,8 @@ class Thread {
bool announced_;
+ bool random_state_inited_; // Whether InitRandomState() has been called.
+
friend struct ThreadListHead;
};