[compiler-rt] [compiler-rt][asan] _aligned_malloc/_aligned_free interception. (PR #82049)
David CARLIER via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 8 08:09:04 PST 2024
https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/82049
>From c8cec9c0c2828ffa6d376dfc595993196718c8cf 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/5] [compiler-rt][asan] _aligned_malloc/_aligned_free
interception.
---
compiler-rt/lib/asan/asan_malloc_win.cpp | 20 +++++++++++++++++++
.../asan/TestCases/Windows/aligned_alloc.cpp | 20 +++++++++++++++++++
2 files changed, 40 insertions(+)
create mode 100644 compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index 3278f072198769..213eb6587b52bd 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -142,6 +142,26 @@ __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 alignment, size_t size) {
+ GET_STACK_TRACE_MALLOC;
+ return asan_aligned_alloc(alignment, size, &stack);
+}
+
+__declspec(noinline) void *_aligned_realloc(void *p, size_t alignment,
+ size_t size) {
+ 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) 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.
diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
new file mode 100644
index 00000000000000..569e3616354015
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cl_asan %Od %s %Fe%t
+// RUN: %run %t
+
+#include <windows.h>
+
+#define CHECK_ALIGNED(ptr, alignment) \
+ do { \
+ if (((uintptr_t)(ptr) % (alignment)) != 0) \
+ return __LINE__; \
+ } while (0)
+
+int main(void) {
+ char *p = reinterpret_cast<char *>(_aligned_malloc(16, 8);
+ CHECK_ALIGNED(p, 8);
+ char *n = reinterpret_cast<char *>(_aligned_realloc(32, 16));
+ CHECK_ALIGNED(n, 16);
+ _aligned_free(n);
+
+ return 0;
+}
>From 14bc9fda663612956c6a3b191a6868393e7379e7 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Mon, 4 Nov 2024 20:09:30 +0000
Subject: [PATCH 2/5] changes from feedback
---
compiler-rt/lib/asan/asan_malloc_win.cpp | 19 +++++++++++++------
.../asan/TestCases/Windows/aligned_alloc.cpp | 7 ++++++-
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index 213eb6587b52bd..ce5d40b7fbd097 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -142,13 +142,13 @@ __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 alignment, size_t 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 alignment,
- size_t size) {
+__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) {
@@ -162,6 +162,12 @@ __declspec(noinline) void *_aligned_realloc(void *p, size_t alignment,
__declspec(noinline) void *_aligned_free(void *p) { free(p); }
+__declspec(noinline) size_t _aligned_msize(void *p) {
+ GET_CURRENT_PC_BP_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.
@@ -193,9 +199,6 @@ __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().
-
int _CrtDbgReport(int, const char*, int,
const char*, const char*, ...) {
ShowStatsAndAbort();
@@ -515,6 +518,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/test/asan/TestCases/Windows/aligned_alloc.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
index 569e3616354015..540d93324f47a1 100644
--- a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
@@ -10,11 +10,16 @@
} while (0)
int main(void) {
- char *p = reinterpret_cast<char *>(_aligned_malloc(16, 8);
+ char *p = reinterpret_cast<char *>(_aligned_malloc(16, 8));
CHECK_ALIGNED(p, 8);
char *n = reinterpret_cast<char *>(_aligned_realloc(32, 16));
CHECK_ALIGNED(n, 16);
_aligned_free(n);
+ p = reinterpret_cast<char *>(_aligned_malloc(128, 8));
+ CHECK_ALIGNED(p, 8);
+ p[-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 a735ddadda3aebd4cafe154c133e13cb8e913bfd Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Mon, 4 Nov 2024 23:20:34 +0000
Subject: [PATCH 3/5] fix build
---
compiler-rt/lib/asan/asan_malloc_win.cpp | 3 ++-
compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index ce5d40b7fbd097..ac6a095bed4959 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -160,10 +160,11 @@ __declspec(noinline) void *_aligned_realloc(void *p, size_t size,
return n;
}
-__declspec(noinline) void *_aligned_free(void *p) { free(p); }
+__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);
}
diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
index 540d93324f47a1..2a75c3a1f2ffef 100644
--- a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
+++ b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
@@ -18,8 +18,8 @@ int main(void) {
p = reinterpret_cast<char *>(_aligned_malloc(128, 8));
CHECK_ALIGNED(p, 8);
p[-1] = 'a';
-// CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
-// CHECK: WRITE of size 1 at [[ADDR]] thread T0
+ // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
+ // CHECK: WRITE of size 1 at [[ADDR]] thread T0
return 0;
}
>From cf92c39b89eea7a20adaa038f450b537294353ef Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Thu, 7 Nov 2024 23:31:39 +0000
Subject: [PATCH 4/5] tests changes from reviews.
---
.../asan/TestCases/Windows/aligned_alloc.cpp | 25 -------------------
.../TestCases/Windows/aligned_mallocs.cpp | 6 ++++-
2 files changed, 5 insertions(+), 26 deletions(-)
delete mode 100644 compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
deleted file mode 100644
index 2a75c3a1f2ffef..00000000000000
--- a/compiler-rt/test/asan/TestCases/Windows/aligned_alloc.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cl_asan %Od %s %Fe%t
-// RUN: %run %t
-
-#include <windows.h>
-
-#define CHECK_ALIGNED(ptr, alignment) \
- do { \
- if (((uintptr_t)(ptr) % (alignment)) != 0) \
- return __LINE__; \
- } while (0)
-
-int main(void) {
- char *p = reinterpret_cast<char *>(_aligned_malloc(16, 8));
- CHECK_ALIGNED(p, 8);
- char *n = reinterpret_cast<char *>(_aligned_realloc(32, 16));
- CHECK_ALIGNED(n, 16);
- _aligned_free(n);
- p = reinterpret_cast<char *>(_aligned_malloc(128, 8));
- CHECK_ALIGNED(p, 8);
- p[-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;
-}
diff --git a/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp b/compiler-rt/test/asan/TestCases/Windows/aligned_mallocs.cpp
index ee6ec4495e7c8f..2277fcfe96d8cd 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: %run %t | 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 4bff3cc1015a6cfb40517b8d158266335adf7d92 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Fri, 8 Nov 2024 12:57:55 +0000
Subject: [PATCH 5/5] windows thunk part
---
compiler-rt/lib/asan/asan_malloc_win.cpp | 12 ++++++++++
.../lib/asan/asan_malloc_win_thunk.cpp | 22 +++++++++++++++++++
.../TestCases/Windows/aligned_mallocs.cpp | 2 +-
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index ac6a095bed4959..61f8d709389b26 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -200,6 +200,18 @@ __declspec(dllexport) void *__cdecl __asan_recalloc(void *const ptr,
return _recalloc(ptr, nmemb, size);
}
+__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*, ...) {
ShowStatsAndAbort();
diff --git a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp b/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
index 9cc00913177eab..b4d2a63d9794c4 100644
--- a/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win_thunk.cpp
@@ -33,6 +33,12 @@ __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 +147,22 @@ 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 2277fcfe96d8cd..4a2fa0be787fd7 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 | FileCheck %s
+// RUN: not %run %t | FileCheck %s
#include <windows.h>
More information about the llvm-commits
mailing list