Merge commit a5fa4dba6e2e from llvm-project (by PiJoules):

[compiler-rt] Add interceptors for free_[aligned_]sized for asan+hwasan (#189109)

This avoids a jemalloc assertion when running sanitized applications
against glib, which uses free_sized(3).

PR:		298943
MFC after:	1 week

(cherry picked from commit a3fbf20c05)
This commit is contained in:
Dimitry Andric committed 2026-10-17 12:21:07 +02:00
1 parent 4192a88ff5
commit d526521ef5
4 files changed
+70

No files matched your search

@@ -1011,6 +1011,19 @@ void asan_free(void *ptr, BufferedStackTrace *stack) {
instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
}
// TODO: Both the size and alignment arguments of Allocator::Deallocate
// are actually unused when the alloc type is FROM_MALLOC. We should look
// into why this is the case, but for now passing the arguments like so
// is the correct thing to do.
void asan_free_sized(void* ptr, uptr size, BufferedStackTrace* stack) {
instance.Deallocate(ptr, size, /*delete_alignment=*/0, stack, FROM_MALLOC);
}
void asan_free_aligned_sized(void* ptr, uptr alignment, uptr size,
BufferedStackTrace* stack) {
instance.Deallocate(ptr, size, alignment, stack, FROM_MALLOC);
}
void *asan_malloc(uptr size, BufferedStackTrace *stack) {
return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
}
@@ -272,6 +272,9 @@ struct AsanThreadLocalMallocStorage {
void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack);
void asan_free(void *ptr, BufferedStackTrace *stack);
void asan_free_sized(void* ptr, uptr size, BufferedStackTrace* stack);
void asan_free_aligned_sized(void* ptr, uptr alignment, uptr size,
BufferedStackTrace* stack);
void *asan_malloc(uptr size, BufferedStackTrace *stack);
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
@@ -61,6 +61,28 @@ INTERCEPTOR(void, cfree, void *ptr) {
}
#endif // SANITIZER_INTERCEPT_CFREE
# if SANITIZER_INTERCEPT_FREE_SIZED
INTERCEPTOR(void, free_sized, void* ptr, uptr size) {
if (UNLIKELY(!ptr))
return;
if (DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Free(ptr);
GET_STACK_TRACE_FREE;
asan_free_sized(ptr, size, &stack);
}
# endif // SANITIZER_INTERCEPT_FREE_SIZED
# if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
INTERCEPTOR(void, free_aligned_sized, void* ptr, uptr alignment, uptr size) {
if (UNLIKELY(!ptr))
return;
if (DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Free(ptr);
GET_STACK_TRACE_FREE;
asan_free_aligned_sized(ptr, alignment, size, &stack);
}
# endif // SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
INTERCEPTOR(void*, malloc, uptr size) {
if (DlsymAlloc::Use())
return DlsymAlloc::Allocate(size);
@@ -17,6 +17,7 @@
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
#include "sanitizer_common/sanitizer_mallinfo.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"
using namespace __hwasan;
@@ -96,6 +97,30 @@ void __sanitizer_cfree(void *ptr) {
hwasan_free(ptr, &stack);
}
#if SANITIZER_INTERCEPT_FREE_SIZED
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_free_sized(void* ptr, uptr size) {
if (!ptr)
return;
if (DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Free(ptr);
GET_MALLOC_STACK_TRACE;
hwasan_free(ptr, &stack);
}
#endif
#if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_free_aligned_sized(void* ptr, uptr alignment, uptr size) {
if (!ptr)
return;
if (DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Free(ptr);
GET_MALLOC_STACK_TRACE;
hwasan_free(ptr, &stack);
}
#endif
SANITIZER_INTERFACE_ATTRIBUTE
uptr __sanitizer_malloc_usable_size(const void *ptr) {
return __sanitizer_get_allocated_size(ptr);
@@ -170,6 +195,13 @@ INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size);
INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size);
INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size);
INTERCEPTOR_ALIAS(void, free, void *ptr);
# if SANITIZER_INTERCEPT_FREE_SIZED
INTERCEPTOR_ALIAS(void, free_sized, void* ptr, SIZE_T size);
# endif
# if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
INTERCEPTOR_ALIAS(void, free_aligned_sized, void* ptr, SIZE_T alignment,
SIZE_T size);
# endif
INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr);
INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size);
INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size);