[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