Skip to content

Commit 70a1da1

Browse files
committed
hwasan: refactor interceptor allocation/deallocation functions
Signed-off-by: Justin King <jcking@google.com>
1 parent 3dc9f2d commit 70a1da1

File tree

4 files changed

+207
-70
lines changed

4 files changed

+207
-70
lines changed

compiler-rt/lib/hwasan/hwasan.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,21 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
136136
StackTrace *stack);
137137
void hwasan_free(void *ptr, StackTrace *stack);
138138

139+
void *hwasan_new(uptr size, StackTrace *stack);
140+
void *hwasan_new_aligned(uptr size, uptr alignment, StackTrace *stack);
141+
void *hwasan_new_array(uptr size, StackTrace *stack);
142+
void *hwasan_new_array_aligned(uptr size, uptr alignment, StackTrace *stack);
143+
void hwasan_delete(void *ptr, StackTrace *stack);
144+
void hwasan_delete_aligned(void *ptr, uptr alignment, StackTrace *stack);
145+
void hwasan_delete_sized(void *ptr, uptr size, StackTrace *stack);
146+
void hwasan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
147+
StackTrace *stack);
148+
void hwasan_delete_array(void *ptr, StackTrace *stack);
149+
void hwasan_delete_array_aligned(void *ptr, uptr alignment, StackTrace *stack);
150+
void hwasan_delete_array_sized(void *ptr, uptr size, StackTrace *stack);
151+
void hwasan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
152+
StackTrace *stack);
153+
139154
void InstallAtExitHandler();
140155

141156
#define GET_MALLOC_STACK_TRACE \

compiler-rt/lib/hwasan/hwasan_allocator.cpp

Lines changed: 115 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ inline __lsan::ChunkTag Metadata::GetLsanTag() const {
128128
return static_cast<__lsan::ChunkTag>(lsan_tag);
129129
}
130130

131+
inline void Metadata::SetAllocType(AllocType type) { alloc_type = type; }
132+
133+
inline AllocType Metadata::GetAllocType() const {
134+
return static_cast<AllocType>(alloc_type);
135+
}
136+
131137
uptr GetAliasRegionStart() {
132138
#if defined(HWASAN_ALIASING_MODE)
133139
constexpr uptr kAliasRegionOffset = 1ULL << (kTaggableRegionCheckShift - 1);
@@ -181,7 +187,7 @@ static uptr TaggedSize(uptr size) {
181187
}
182188

183189
static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
184-
bool zeroise) {
190+
AllocType alloc_type, bool zeroise) {
185191
// Keep this consistent with LSAN and ASAN behavior.
186192
if (UNLIKELY(orig_size == 0))
187193
orig_size = 1;
@@ -259,6 +265,7 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
259265
meta->SetLsanTag(__lsan::DisabledInThisThread() ? __lsan::kIgnored
260266
: __lsan::kDirectlyLeaked);
261267
#endif
268+
meta->SetAllocType(alloc_type);
262269
meta->SetAllocated(StackDepotPut(*stack), orig_size);
263270
RunMallocHooks(user_ptr, orig_size);
264271
return user_ptr;
@@ -285,7 +292,7 @@ static bool CheckInvalidFree(StackTrace *stack, void *untagged_ptr,
285292
return false;
286293
}
287294

288-
static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
295+
static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr, AllocType) {
289296
CHECK(tagged_ptr);
290297
void *untagged_ptr = UntagPtr(tagged_ptr);
291298

@@ -379,15 +386,15 @@ static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old,
379386
void *untagged_ptr_old = UntagPtr(tagged_ptr_old);
380387
if (CheckInvalidFree(stack, untagged_ptr_old, tagged_ptr_old))
381388
return nullptr;
382-
void *tagged_ptr_new =
383-
HwasanAllocate(stack, new_size, alignment, false /*zeroise*/);
389+
void *tagged_ptr_new = HwasanAllocate(stack, new_size, alignment, FROM_MALLOC,
390+
false /*zeroise*/);
384391
if (tagged_ptr_old && tagged_ptr_new) {
385392
Metadata *meta =
386393
reinterpret_cast<Metadata *>(allocator.GetMetaData(untagged_ptr_old));
387394
void *untagged_ptr_new = UntagPtr(tagged_ptr_new);
388395
internal_memcpy(untagged_ptr_new, untagged_ptr_old,
389396
Min(new_size, static_cast<uptr>(meta->GetRequestedSize())));
390-
HwasanDeallocate(stack, tagged_ptr_old);
397+
HwasanDeallocate(stack, tagged_ptr_old, FROM_MALLOC);
391398
}
392399
return tagged_ptr_new;
393400
}
@@ -398,7 +405,7 @@ static void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
398405
return nullptr;
399406
ReportCallocOverflow(nmemb, size, stack);
400407
}
401-
return HwasanAllocate(stack, nmemb * size, sizeof(u64), true);
408+
return HwasanAllocate(stack, nmemb * size, sizeof(u64), FROM_MALLOC, true);
402409
}
403410

404411
HwasanChunkView FindHeapChunkByAddress(uptr address) {
@@ -449,7 +456,8 @@ static uptr AllocationSizeFast(const void *p) {
449456
}
450457

451458
void *hwasan_malloc(uptr size, StackTrace *stack) {
452-
return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
459+
return SetErrnoOnNull(
460+
HwasanAllocate(stack, size, sizeof(u64), FROM_MALLOC, false));
453461
}
454462

455463
void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
@@ -458,9 +466,10 @@ void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
458466

459467
void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack) {
460468
if (!ptr)
461-
return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
469+
return SetErrnoOnNull(
470+
HwasanAllocate(stack, size, sizeof(u64), FROM_MALLOC, false));
462471
if (size == 0) {
463-
HwasanDeallocate(stack, ptr);
472+
HwasanDeallocate(stack, ptr, FROM_MALLOC);
464473
return nullptr;
465474
}
466475
return SetErrnoOnNull(HwasanReallocate(stack, ptr, size, sizeof(u64)));
@@ -478,7 +487,7 @@ void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
478487

479488
void *hwasan_valloc(uptr size, StackTrace *stack) {
480489
return SetErrnoOnNull(
481-
HwasanAllocate(stack, size, GetPageSizeCached(), false));
490+
HwasanAllocate(stack, size, GetPageSizeCached(), FROM_MALLOC, false));
482491
}
483492

484493
void *hwasan_pvalloc(uptr size, StackTrace *stack) {
@@ -491,7 +500,8 @@ void *hwasan_pvalloc(uptr size, StackTrace *stack) {
491500
}
492501
// pvalloc(0) should allocate one page.
493502
size = size ? RoundUpTo(size, PageSize) : PageSize;
494-
return SetErrnoOnNull(HwasanAllocate(stack, size, PageSize, false));
503+
return SetErrnoOnNull(
504+
HwasanAllocate(stack, size, PageSize, FROM_MALLOC, false));
495505
}
496506

497507
void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
@@ -501,7 +511,8 @@ void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) {
501511
return nullptr;
502512
ReportInvalidAlignedAllocAlignment(size, alignment, stack);
503513
}
504-
return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
514+
return SetErrnoOnNull(
515+
HwasanAllocate(stack, size, alignment, FROM_MALLOC, false));
505516
}
506517

507518
void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) {
@@ -511,7 +522,8 @@ void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) {
511522
return nullptr;
512523
ReportInvalidAllocationAlignment(alignment, stack);
513524
}
514-
return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false));
525+
return SetErrnoOnNull(
526+
HwasanAllocate(stack, size, alignment, FROM_MALLOC, false));
515527
}
516528

517529
int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
@@ -521,7 +533,7 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
521533
return errno_EINVAL;
522534
ReportInvalidPosixMemalignAlignment(alignment, stack);
523535
}
524-
void *ptr = HwasanAllocate(stack, size, alignment, false);
536+
void *ptr = HwasanAllocate(stack, size, alignment, FROM_MALLOC, false);
525537
if (UNLIKELY(!ptr))
526538
// OOM error is already taken care of by HwasanAllocate.
527539
return errno_ENOMEM;
@@ -531,7 +543,95 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
531543
}
532544

533545
void hwasan_free(void *ptr, StackTrace *stack) {
534-
return HwasanDeallocate(stack, ptr);
546+
HwasanDeallocate(stack, ptr, FROM_MALLOC);
547+
}
548+
549+
namespace {
550+
551+
void *hwasan_new(uptr size, StackTrace *stack, bool array) {
552+
return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64),
553+
array ? FROM_NEW_BR : FROM_NEW, true));
554+
}
555+
556+
void *hwasan_new_aligned(uptr size, uptr alignment, StackTrace *stack,
557+
bool array) {
558+
if (UNLIKELY(alignment == 0 || !IsPowerOfTwo(alignment))) {
559+
errno = errno_EINVAL;
560+
if (AllocatorMayReturnNull())
561+
return nullptr;
562+
ReportInvalidAllocationAlignment(alignment, stack);
563+
}
564+
return SetErrnoOnNull(HwasanAllocate(stack, size, alignment,
565+
array ? FROM_NEW_BR : FROM_NEW, false));
566+
}
567+
568+
void hwasan_delete(void *ptr, StackTrace *stack, bool array) {
569+
HwasanDeallocate(stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
570+
}
571+
572+
void hwasan_delete_aligned(void *ptr, uptr, StackTrace *stack, bool array) {
573+
HwasanDeallocate(stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
574+
}
575+
576+
void hwasan_delete_sized(void *ptr, uptr, StackTrace *stack, bool array) {
577+
HwasanDeallocate(stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
578+
}
579+
580+
void hwasan_delete_sized_aligned(void *ptr, uptr, uptr, StackTrace *stack,
581+
bool array) {
582+
HwasanDeallocate(stack, ptr, array ? FROM_NEW_BR : FROM_NEW);
583+
}
584+
585+
} // namespace
586+
587+
void *hwasan_new(uptr size, StackTrace *stack) {
588+
return hwasan_new(size, stack, /*array=*/false);
589+
}
590+
591+
void *hwasan_new_aligned(uptr size, uptr alignment, StackTrace *stack) {
592+
return hwasan_new_aligned(size, alignment, stack, /*array=*/false);
593+
}
594+
595+
void *hwasan_new_array(uptr size, StackTrace *stack) {
596+
return hwasan_new(size, stack, /*array=*/true);
597+
}
598+
599+
void *hwasan_new_array_aligned(uptr size, uptr alignment, StackTrace *stack) {
600+
return hwasan_new_aligned(size, alignment, stack, /*array=*/true);
601+
}
602+
603+
void hwasan_delete(void *ptr, StackTrace *stack) {
604+
hwasan_delete(ptr, stack, /*array=*/false);
605+
}
606+
607+
void hwasan_delete_aligned(void *ptr, uptr alignment, StackTrace *stack) {
608+
hwasan_delete_aligned(ptr, alignment, stack, /*array=*/false);
609+
}
610+
611+
void hwasan_delete_sized(void *ptr, uptr size, StackTrace *stack) {
612+
hwasan_delete_sized(ptr, size, stack, /*array=*/false);
613+
}
614+
615+
void hwasan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
616+
StackTrace *stack) {
617+
hwasan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/false);
618+
}
619+
620+
void hwasan_delete_array(void *ptr, StackTrace *stack) {
621+
hwasan_delete(ptr, stack, /*array=*/true);
622+
}
623+
624+
void hwasan_delete_array_aligned(void *ptr, uptr alignment, StackTrace *stack) {
625+
hwasan_delete_aligned(ptr, alignment, stack, /*array=*/true);
626+
}
627+
628+
void hwasan_delete_array_sized(void *ptr, uptr size, StackTrace *stack) {
629+
hwasan_delete_sized(ptr, size, stack, /*array=*/true);
630+
}
631+
632+
void hwasan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
633+
StackTrace *stack) {
634+
hwasan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/true);
535635
}
536636

537637
} // namespace __hwasan

compiler-rt/lib/hwasan/hwasan_allocator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@
3131

3232
namespace __hwasan {
3333

34+
enum AllocType {
35+
FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
36+
FROM_NEW = 2, // Memory block came from operator new.
37+
FROM_NEW_BR = 3 // Memory block came from operator new [ ]
38+
};
39+
3440
struct Metadata {
3541
private:
3642
atomic_uint64_t alloc_context_id;
3743
u32 requested_size_low;
3844
u16 requested_size_high;
3945
atomic_uint8_t chunk_state;
40-
u8 lsan_tag;
46+
u8 lsan_tag : 2;
47+
u8 alloc_type : 2;
4148

4249
public:
4350
inline void SetAllocated(u32 stack, u64 size);
@@ -49,6 +56,8 @@ struct Metadata {
4956
inline u32 GetAllocThreadId() const;
5057
inline void SetLsanTag(__lsan::ChunkTag tag);
5158
inline __lsan::ChunkTag GetLsanTag() const;
59+
inline void SetAllocType(AllocType type);
60+
inline AllocType GetAllocType() const;
5261
};
5362
static_assert(sizeof(Metadata) == 16);
5463

0 commit comments

Comments
 (0)