[compiler-rt] 1b0d63c - [HWASAN] Implemented LsanMetadata in HWASAN.
Kirill Stoimenov via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 13 09:05:26 PST 2022
Author: Kirill Stoimenov
Date: 2022-12-13T17:05:15Z
New Revision: 1b0d63c506c042045792cd98c0dd2be912b6a96d
URL: https://github.com/llvm/llvm-project/commit/1b0d63c506c042045792cd98c0dd2be912b6a96d
DIFF: https://github.com/llvm/llvm-project/commit/1b0d63c506c042045792cd98c0dd2be912b6a96d.diff
LOG: [HWASAN] Implemented LsanMetadata in HWASAN.
Please note that that this code is not used. It will be connected at some point when the rest of the code is ready.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D139464
Added:
Modified:
compiler-rt/lib/hwasan/hwasan_allocator.cpp
compiler-rt/lib/hwasan/hwasan_allocator.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
index 102c2bdbc07f7..42456e57fc3bd 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
@@ -21,6 +21,7 @@
#include "hwasan_malloc_bisect.h"
#include "hwasan_thread.h"
#include "hwasan_report.h"
+#include "lsan/lsan_common.h"
namespace __hwasan {
@@ -32,18 +33,21 @@ static atomic_uint8_t hwasan_allocator_tagging_enabled;
static constexpr tag_t kFallbackAllocTag = 0xBB & kTagMask;
static constexpr tag_t kFallbackFreeTag = 0xBC;
-enum RightAlignMode {
- kRightAlignNever,
- kRightAlignSometimes,
- kRightAlignAlways
+enum {
+ // Either just allocated by underlying allocator, but AsanChunk is not yet
+ // ready, or almost returned to undelying allocator and AsanChunk is already
+ // meaningless.
+ CHUNK_INVALID = 0,
+ // The chunk is allocated and not yet freed.
+ CHUNK_ALLOCATED = 1,
};
+
// Initialized in HwasanAllocatorInit, an never changed.
static ALIGNED(16) u8 tail_magic[kShadowAlignment - 1];
bool HwasanChunkView::IsAllocated() const {
- return metadata_ && metadata_->alloc_context_id &&
- metadata_->GetRequestedSize();
+ return metadata_ && metadata_->IsAllocated();
}
uptr HwasanChunkView::Beg() const {
@@ -56,7 +60,7 @@ uptr HwasanChunkView::UsedSize() const {
return metadata_->GetRequestedSize();
}
u32 HwasanChunkView::GetAllocStackId() const {
- return metadata_->alloc_context_id;
+ return metadata_->GetAllocStackId();
}
uptr HwasanChunkView::ActualSize() const {
@@ -67,10 +71,51 @@ bool HwasanChunkView::FromSmallHeap() const {
return allocator.FromPrimary(reinterpret_cast<void *>(block_));
}
+inline void Metadata::SetAllocated(u32 stack, u64 size) {
+ Thread *t = GetCurrentThread();
+ u64 context = t ? t->unique_id() : kMainTid;
+ context <<= 32;
+ context += stack;
+ requested_size_low = size & ((1ul << 32) - 1);
+ requested_size_high = size >> 32;
+ atomic_store(&alloc_context_id, context, memory_order_relaxed);
+ atomic_store(&chunk_state, CHUNK_ALLOCATED, memory_order_release);
+}
+
+inline void Metadata::SetUnallocated() {
+ atomic_store(&chunk_state, CHUNK_INVALID, memory_order_release);
+ requested_size_low = 0;
+ requested_size_high = 0;
+ atomic_store(&alloc_context_id, 0, memory_order_relaxed);
+}
+
+inline bool Metadata::IsAllocated() const {
+ return atomic_load(&chunk_state, memory_order_relaxed) == CHUNK_ALLOCATED &&
+ GetRequestedSize();
+}
+
+inline u64 Metadata::GetRequestedSize() const {
+ return (static_cast<u64>(requested_size_high) << 32) + requested_size_low;
+}
+
+inline u32 Metadata::GetAllocStackId() const {
+ return atomic_load(&alloc_context_id, memory_order_relaxed);
+}
+
+static const uptr kChunkHeaderSize = sizeof(HwasanChunkView);
+
void GetAllocatorStats(AllocatorStatCounters s) {
allocator.GetStats(s);
}
+inline void Metadata::SetLsanTag(__lsan::ChunkTag tag) {
+ lsan_tag = tag;
+}
+
+inline __lsan::ChunkTag Metadata::GetLsanTag() const {
+ return static_cast<__lsan::ChunkTag>(lsan_tag);
+}
+
uptr GetAliasRegionStart() {
#if defined(HWASAN_ALIASING_MODE)
constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1);
@@ -146,10 +191,6 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
return nullptr;
ReportOutOfMemory(size, stack);
}
- Metadata *meta =
- reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
- meta->SetRequestedSize(orig_size);
- meta->alloc_context_id = StackDepotPut(*stack);
if (zeroise) {
internal_memset(allocated, 0, size);
} else if (flags()->max_malloc_fill_size > 0) {
@@ -189,6 +230,9 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
}
}
+ Metadata *meta =
+ reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
+ meta->SetAllocated(StackDepotPut(*stack), orig_size);
RunMallocHooks(user_ptr, size);
return user_ptr;
}
@@ -236,7 +280,7 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
}
uptr orig_size = meta->GetRequestedSize();
u32 free_context_id = StackDepotPut(*stack);
- u32 alloc_context_id = meta->alloc_context_id;
+ u32 alloc_context_id = meta->GetAllocStackId();
// Check tail magic.
uptr tagged_size = TaggedSize(orig_size);
@@ -255,8 +299,8 @@ static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
orig_size, tail_magic);
}
- meta->SetRequestedSize(0);
- meta->alloc_context_id = 0;
+ // TODO(kstoimenov): consider meta->SetUnallocated(free_context_id).
+ meta->SetUnallocated();
// This memory will not be reused by anyone else, so we are free to keep it
// poisoned.
Thread *t = GetCurrentThread();
@@ -435,6 +479,44 @@ void hwasan_free(void *ptr, StackTrace *stack) {
} // namespace __hwasan
+// --- Implementation of LSan-specific functions --- {{{1
+namespace __lsan {
+
+LsanMetadata::LsanMetadata(uptr chunk) {
+ metadata_ = chunk ? reinterpret_cast<__hwasan::Metadata *>(
+ chunk - __hwasan::kChunkHeaderSize)
+ : nullptr;
+}
+
+bool LsanMetadata::allocated() const {
+ if (!metadata_)
+ return false;
+ __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
+ return m->IsAllocated();
+}
+
+ChunkTag LsanMetadata::tag() const {
+ __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
+ return m->GetLsanTag();
+}
+
+void LsanMetadata::set_tag(ChunkTag value) {
+ __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
+ m->SetLsanTag(value);
+}
+
+uptr LsanMetadata::requested_size() const {
+ __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
+ return m->GetRequestedSize();
+}
+
+u32 LsanMetadata::stack_trace_id() const {
+ __hwasan::Metadata *m = reinterpret_cast<__hwasan::Metadata *>(metadata_);
+ return m->GetAllocStackId();
+}
+
+} // namespace __lsan
+
using namespace __hwasan;
void __hwasan_enable_allocator_tagging() {
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h
index 396abf216d48e..6ba8e40eb840f 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.h
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.h
@@ -17,6 +17,7 @@
#include "hwasan_interface_internal.h"
#include "hwasan_mapping.h"
#include "hwasan_poisoning.h"
+#include "lsan/lsan_common.h"
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_checks.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
@@ -31,17 +32,24 @@
namespace __hwasan {
struct Metadata {
+ private:
+ atomic_uint64_t alloc_context_id;
u32 requested_size_low;
- u32 requested_size_high;
- u32 alloc_context_id;
- u64 GetRequestedSize() {
- return (static_cast<u64>(requested_size_high) << 32) + requested_size_low;
- }
- void SetRequestedSize(u64 size) {
- requested_size_low = size & ((1ul << 32) - 1);
- requested_size_high = size >> 32;
- }
+ u16 requested_size_high;
+ atomic_uint8_t chunk_state;
+ u8 lsan_tag;
+
+ public:
+ inline void SetAllocated(u32 stack, u64 size);
+ inline void SetUnallocated();
+
+ inline bool IsAllocated() const;
+ inline u64 GetRequestedSize() const;
+ inline u32 GetAllocStackId() const;
+ inline void SetLsanTag(__lsan::ChunkTag tag);
+ inline __lsan::ChunkTag GetLsanTag() const;
};
+static_assert(sizeof(Metadata) == 16);
struct HwasanMapUnmapCallback {
void OnMap(uptr p, uptr size) const { UpdateMemoryUsage(); }
@@ -88,6 +96,7 @@ class HwasanChunkView {
u32 GetAllocStackId() const;
bool FromSmallHeap() const;
private:
+ friend class __lsan::LsanMetadata;
uptr block_;
Metadata *const metadata_;
};
More information about the llvm-commits
mailing list