[compiler-rt] [compiler-rt][asan] _aligned_malloc/_aligned_free interception. (PR #82049)

David CARLIER via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 14 11:21:10 PST 2024


https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/82049

>From 5f7cf844731c5cd2a597fb6dcbf9a8f9028c54a8 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Fri, 16 Feb 2024 22:08:25 +0000
Subject: [PATCH 1/2] [compiler-rt][asan] _aligned_malloc/_aligned_free
 interception.

---
 compiler-rt/lib/asan/asan_malloc_win.cpp      | 42 ++++++++++++++++++-
 .../lib/asan/asan_malloc_win_thunk.cpp        | 19 +++++++++
 .../TestCases/Windows/aligned_mallocs.cpp     |  6 ++-
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index 3278f072198769..7dd675a5eb63d8 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -142,6 +142,33 @@ __declspec(noinline) void *_recalloc_base(void *p, size_t n, size_t elem_size) {
   return _recalloc(p, n, elem_size);
 }
 
+__declspec(noinline) void *_aligned_malloc(size_t size, size_t alignment) {
+  GET_STACK_TRACE_MALLOC;
+  return asan_aligned_alloc(alignment, size, &stack);
+}
+
+__declspec(noinline) void *_aligned_realloc(void *p, size_t size,
+                                            size_t alignment) {
+  GET_STACK_TRACE_MALLOC;
+  void *n = asan_aligned_alloc(alignment, size, &stack);
+  if (n) {
+    size_t osize = _msize(p);
+    REAL(memcpy)(n, p, Min<size_t>(osize, size));
+    free(p);
+  }
+
+  return n;
+}
+
+__declspec(noinline) void _aligned_free(void *p) { free(p); }
+
+__declspec(noinline) size_t _aligned_msize(void *p) {
+  GET_CURRENT_PC_BP_SP;
+  (void)sp;
+
+  return asan_malloc_usable_size(p, pc, bp);
+}
+
 __declspec(noinline) void *_expand(void *memblock, size_t size) {
   // _expand is used in realloc-like functions to resize the buffer if possible.
   // We don't want memory to stand still while resizing buffers, so return 0.
@@ -173,8 +200,15 @@ __declspec(dllexport) void *__cdecl __asan_recalloc(void *const ptr,
   return _recalloc(ptr, nmemb, size);
 }
 
-// TODO(timurrrr): Might want to add support for _aligned_* allocation
-// functions to detect a bit more bugs.  Those functions seem to wrap malloc().
+__declspec(dllexport) void *__cdecl __asan_aligned_malloc(
+    const size_t size, const size_t alignment) {
+  return _aligned_malloc(size, alignment);
+}
+
+__declspec(dllexport) void *__cdecl __asan_aligned_realloc(
+    void *const ptr, const size_t size, const size_t alignment) {
+  return _aligned_realloc(ptr, size, alignment);
+}
 
 int _CrtDbgReport(int, const char*, int,
                   const char*, const char*, ...) {
@@ -495,6 +529,10 @@ void ReplaceSystemMalloc() {
   TryToOverrideFunction("_msize_base", (uptr)_msize);
   TryToOverrideFunction("_expand", (uptr)_expand);
   TryToOverrideFunction("_expand_base", (uptr)_expand);
+  TryToOverrideFunction("_aligned_malloc", (uptr)_aligned_malloc);
+  TryToOverrideFunction("_aligned_realloc", (uptr)_aligned_realloc);
+  TryToOverrideFunction("_aligned_free", (uptr)_aligned_free);
+  TryToOverrideFunction("_aligned_msize", (uptr)_aligned_msize);
 
   if (flags()->windows_hook_rtl_allocators) {
     ASAN_INTERCEPT_FUNC(HeapSize);
diff --git a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp b/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
index 9cc00913177eab..9dbb8dae40f45f 100644
--- a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
@@ -33,6 +33,11 @@ __declspec(dllimport) void *__cdecl __asan_realloc(void *const ptr,
 __declspec(dllimport) void *__cdecl __asan_recalloc(void *const ptr,
                                                     const size_t nmemb,
                                                     const size_t size);
+__declspec(dllimport) void *__cdecl __asan_aligned_malloc(
+    const size_t size, const size_t alignment);
+
+__declspec(dllimport) void *__cdecl __asan_aligned_realloc(
+    void *const ptr, const size_t size, const size_t alignment);
 
 // Avoid tailcall optimization to preserve stack frames.
 #  pragma optimize("", off)
@@ -141,6 +146,20 @@ STATIC_MALLOC_INTERFACE void *_expand_dbg(void *, size_t, int, const char *,
   return nullptr;
 }
 
+// _aligned
+STATIC_MALLOC_INTERFACE void *_aligned_malloc(size_t size, size_t alignment) {
+  return __asan_aligned_malloc(size, alignment);
+}
+
+STATIC_MALLOC_INTERFACE void *_aligned_realloc(void *ptr, size_t size,
+                                               size_t alignment) {
+  return __asan_aligned_realloc(ptr, size, alignment);
+}
+
+STATIC_MALLOC_INTERFACE void _aligned_free(void *ptr) { __asan_free(ptr); }
+
+STATIC_MALLOC_INTERFACE size_t _aligned_msize(void *ptr) { return _msize(ptr); }
+
 // We need to provide symbols for all the debug CRT functions if we decide to
 // provide any. Most of these functions make no sense under ASan and so we
 // make them no-ops.
diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
index ee6ec4495e7c8f..3d507afb610ade 100644
--- a/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cl_asan %Od %s %Fe%t
-// RUN: %run %t
+// RUN: not %run %t 2>&1 | FileCheck %s
 
 #include <windows.h>
 
@@ -30,6 +30,10 @@ int main(void) {
   if (_aligned_msize(p, 128, 0) != 2048 * sizeof(int))
     return __LINE__;
   _aligned_free(p);
+  char *t = (char *)_aligned_malloc(128, 8);
+  t[-1] = 'a';
+  // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+  // CHECK: WRITE of size 1 at [[ADDR]] thread T0
 
   return 0;
 }

>From a9e3833e4786ec3fd1d26735dd6a648b4a74850c Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Thu, 14 Nov 2024 19:12:28 +0000
Subject: [PATCH 2/2] extend test

---
 .../test/asan/TestCases/Windows/aligned_mallocs.cpp       | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
index 3d507afb610ade..d6a5df8c6a9c7c 100644
--- a/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
@@ -30,6 +30,14 @@ int main(void) {
   if (_aligned_msize(p, 128, 0) != 2048 * sizeof(int))
     return __LINE__;
   _aligned_free(p);
+ 
+  char *y = (char *)malloc(1024);
+  char *u = (char *)realloc(y, 2048);
+  u[0] = 'a';
+  _aligned_free(u);
+  u = (char *)_aligned_offset_malloc(1024, 8, 2);
+  _aligned_free(u);
+
   char *t = (char *)_aligned_malloc(128, 8);
   t[-1] = 'a';
   // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]



More information about the llvm-commits mailing list