Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
Source project has a limited visibility.
  • Cheng Shao's avatar
    c6574dc0
    rts: fix pointer overflow undefined behavior in bytecode interpreter · c6574dc0
    Cheng Shao authored and Andreas Klebinger's avatar Andreas Klebinger committed
    This patch fixes an unnoticed undefined behavior in the bytecode
    interpreter. It can be caught by building `rts/Interpreter.c` with
    `-fsanitize=pointer-overflow`, the warning message is something like:
    
    ```
    rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13
    rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13
    rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13
    ```
    
    Whenever we do something like `SpW(-1)`, the negative argument is
    implicitly converted to an unsigned integer type and causes pointer
    arithmetic overflow. It happens to be harmless for most targets since
    overflowing would wrap the result to desired value, but it's still
    coincidental and undefined behavior. Furthermore, it causes real
    damage to the wasm backend, given clang-20 will emit invalid wasm code
    that crashes at run-time for this kind of C code! (see
    https://github.com/llvm/llvm-project/issues/108770)
    
    The fix here is adding some explicit casts to ensure we always use the
    signed `ptrdiff_t` type as right hand operand of pointer arithmetic.
    
    (cherry picked from commit 5bcfefd5)
    c6574dc0
    History
    rts: fix pointer overflow undefined behavior in bytecode interpreter
    Cheng Shao authored and Andreas Klebinger's avatar Andreas Klebinger committed
    This patch fixes an unnoticed undefined behavior in the bytecode
    interpreter. It can be caught by building `rts/Interpreter.c` with
    `-fsanitize=pointer-overflow`, the warning message is something like:
    
    ```
    rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13
    rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13
    rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13
    ```
    
    Whenever we do something like `SpW(-1)`, the negative argument is
    implicitly converted to an unsigned integer type and causes pointer
    arithmetic overflow. It happens to be harmless for most targets since
    overflowing would wrap the result to desired value, but it's still
    coincidental and undefined behavior. Furthermore, it causes real
    damage to the wasm backend, given clang-20 will emit invalid wasm code
    that crashes at run-time for this kind of C code! (see
    https://github.com/llvm/llvm-project/issues/108770)
    
    The fix here is adding some explicit casts to ensure we always use the
    signed `ptrdiff_t` type as right hand operand of pointer arithmetic.
    
    (cherry picked from commit 5bcfefd5)
Code owners
Assign users and groups as approvers for specific file changes. Learn more.