[compiler-rt] [ASan][Windows] Fix memmove/memcpy interception on x64 (PR #192060)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 06:51:01 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Alexandre Ganea (aganea)
<details>
<summary>Changes</summary>
On Windows x64, memcpy and memmove used to share an implementation in `vcruntime140.dll`, but newer versions of the CRT may provide them as separate functions. Detect this at runtime and intercept accordingly, rather than unconditionally assuming they alias each other.
Should fix https://github.com/llvm/llvm-project/issues/126077
---
Full diff: https://github.com/llvm/llvm-project/pull/192060.diff
2 Files Affected:
- (modified) compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp (-3)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc (+18)
``````````diff
diff --git a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
index 46e0e90738f24..601b0d2dea11f 100644
--- a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
@@ -42,10 +42,7 @@ INTERCEPT_LIBRARY_FUNCTION_ASAN(memchr);
# endif
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcmp);
INTERCEPT_LIBRARY_FUNCTION_ASAN(memcpy);
-# ifndef _WIN64
-// memmove and memcpy share an implementation on amd64
INTERCEPT_LIBRARY_FUNCTION_ASAN(memmove);
-# endif
INTERCEPT_LIBRARY_FUNCTION_ASAN(memset);
INTERCEPT_LIBRARY_FUNCTION_ASAN(strcat);
INTERCEPT_LIBRARY_FUNCTION_ASAN(strchr);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
index 0b6731c89950b..8b50392a45f8d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
@@ -237,8 +237,26 @@ namespace __sanitizer {
// This does not need to be called if InitializeCommonInterceptors() is called.
void InitializeMemintrinsicInterceptors() {
INIT_MEMSET;
+#if SANITIZER_WINDOWS64
+ // On Windows x64, memcpy and memmove used to be the same function in the
+ // CRT (vcruntime140.dll), but newer versions of the runtime may provide
+ // them as separate functions. Detect at runtime before INIT_MEMMOVE
+ // patches the entry point.
+ // Use volatile to prevent the compiler from assuming distinct declarations
+ // imply distinct addresses and folding the comparison to true.
+ volatile uptr memcpy_addr = (uptr)memcpy;
+ volatile uptr memmove_addr = (uptr)memmove;
+ bool memcpy_is_separate = (memcpy_addr != memmove_addr);
+ INIT_MEMMOVE;
+ if (memcpy_is_separate)
+ COMMON_INTERCEPT_FUNCTION(memcpy);
+ else
+ ASSIGN_REAL(memcpy, memmove);
+ CHECK(REAL(memcpy));
+#else
INIT_MEMMOVE;
INIT_MEMCPY;
+#endif
INIT_AEABI_MEM;
INIT___BZERO;
INIT_BZERO;
``````````
</details>
https://github.com/llvm/llvm-project/pull/192060
More information about the llvm-commits
mailing list