[compiler-rt] [ASan][Windows] Fix rip-relative instruction replacement (PR #68432)
nicole mazzuca via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 6 10:26:21 PDT 2023
https://github.com/strega-nil-ms updated https://github.com/llvm/llvm-project/pull/68432
>From f855b36b482aaf8b836ebf87b1ddf83757b70ca5 Mon Sep 17 00:00:00 2001
From: Nicole Mazzuca <nicole at strega-nil.co>
Date: Fri, 6 Oct 2023 10:08:03 -0700
Subject: [PATCH] [ASan][Windows] Fix rip-relative instruction replacement
The old code incorrectly checked what relative offsets were allowed.
The correct check is that the offset from the target to the instruction
pointer should be within [-2**31, 2**31); however, the check that was
originally written was that the offset was within [0, 2**31).
Negative offsets are certainly allowable (as long as they fit in 32 bits),
and this change fixes that.
---
.../lib/interception/interception_win.cpp | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 23d26ea94b51a66..d57afa3fda7bcb8 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -726,16 +726,22 @@ static bool CopyInstructions(uptr to, uptr from, size_t size) {
size_t instruction_size = GetInstructionSize(from + cursor, &rel_offset);
if (!instruction_size)
return false;
- _memcpy((void*)(to + cursor), (void*)(from + cursor),
+ _memcpy((void *)(to + cursor), (void *)(from + cursor),
(size_t)instruction_size);
if (rel_offset) {
- uptr delta = to - from;
- uptr relocated_offset = *(u32*)(to + cursor + rel_offset) - delta;
-#if SANITIZER_WINDOWS64
- if (relocated_offset + 0x80000000U >= 0xFFFFFFFFU)
+# if SANITIZER_WINDOWS64
+ // we want to make sure that the new relative offset still fits in 32-bits
+ // this will be untrue if relocated_offset \notin [-2**31, 2**31)
+ s64 delta = to - from;
+ s64 relocated_offset = *(s32 *)(to + cursor + rel_offset) - delta;
+ if (-0x8000'0000ll > relocated_offset || relocated_offset > 0x7FFF'FFFFll)
return false;
-#endif
- *(u32*)(to + cursor + rel_offset) = relocated_offset;
+# else
+ // on 32-bit, the relative offset will always be correct
+ s32 delta = to - from;
+ s32 relocated_offset = *(s32 *)(to + cursor + rel_offset) - delta;
+# endif
+ *(s32 *)(to + cursor + rel_offset) = relocated_offset;
}
cursor += instruction_size;
}
More information about the llvm-commits
mailing list