[compiler-rt] 694b132 - [sanitizer_common] Fix edge case for stack mapping parsing (#98381)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 13:49:15 PDT 2024
Author: Thurston Dang
Date: 2024-07-10T13:49:11-07:00
New Revision: 694b132177a96a61dac62b3e3d2989a063feafa7
URL: https://github.com/llvm/llvm-project/commit/694b132177a96a61dac62b3e3d2989a063feafa7
DIFF: https://github.com/llvm/llvm-project/commit/694b132177a96a61dac62b3e3d2989a063feafa7.diff
LOG: [sanitizer_common] Fix edge case for stack mapping parsing (#98381)
On some systems (e.g., at least two AArch64 Linux instances), the
process map can have:
```
fffffffdf000-1000000000000 ... [stack]
```
instead of:
```
fffffffdf000- ffffffffffff
```
The stack top value is larger than `GetMaxUserVirtualAddress()`, which
violates the precondition that shadow memory calculations expect. This
patch fixes the issue by saturating off-by-one values (and also adds
checks for more flagrant violations).
This fixes an issue that was observed with DFSan on AArch64 Linux (with
high-entropy ASLR, resulting in ASLR being disabled on some runs):
```
==11057==ERROR: DataflowSanitizer failed to allocate 0x1600000800000 (387028101365760) bytes at address 4fffff800000 (errno: 12)
```
(https://lab.llvm.org/staging/#/builders/90/builds/552/steps/9/logs/stdio)
This was trying to allocate a shadow at `[0x4fffff800000, 0x4fffff800000
+ 0x1600000800000] = [0x4fffff800000, 0x1b00000000000]`. Notice that the
end of the shadow region - an invalid value - is equal to
`MEM_TO_SHADOW(0x1000000000000)`, where `MEM_TO_SHADOW` is defined as
`(mem ^ 0xB00000000000ULL)`.
Added:
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index 175362183fd78..c3c717bbdbe4c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -149,6 +149,19 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
stacksize = kMaxThreadStackSize;
*stack_top = segment.end;
*stack_bottom = segment.end - stacksize;
+
+ uptr maxAddr = GetMaxUserVirtualAddress();
+ // Edge case: the stack mapping on some systems may be off-by-one e.g.,
+ // fffffffdf000-1000000000000 rw-p 00000000 00:00 0 [stack]
+ // instead of:
+ // fffffffdf000- ffffffffffff
+ // The out-of-range stack_top can result in an invalid shadow address
+ // calculation, since those usually assume the parameters are in range.
+ if (*stack_top == maxAddr + 1)
+ *stack_top = maxAddr;
+ else
+ CHECK_LE(*stack_top, maxAddr);
+
return;
}
uptr stacksize = 0;
More information about the llvm-commits
mailing list