[JSC] IPInt fast path for `memory.atomic.wait32`/`wait64` wraps the Memory64 effective address
Every Memory64 load/store in IPInt traps on pointer-overflow. Atomic-wait was the lone holdout — and a pointer near `UINT64_MAX` wraps in-bounds.
Source/JavaScriptCore/llint/InPlaceInterpreter64.asm
IPInt (In-Place Interpreter) is WebKit's assembly-level WebAssembly bytecode interpreter. Memory64 extends Wasm with full i64 addressing, meaning both the runtime base pointer and the static immediate offset encoded in the instruction are 64-bit, making their sum capable of overflowing. The baddpc macro is a carry-aware add already used by regular Memory64 load/store fast paths: it performs the addition and, if the CPU carry flag is set, redirects to _ipint_throw_OutOfBoundsMemoryAccess.
This patch fixes a silent integer overflow in IPInt's Memory64 fast path for memory.atomic.wait32 and memory.atomic.wait64. The effective address computation pointer + offset used an unchecked addq, so a 64-bit pointer near UINT64_MAX plus a non-zero immediate offset would silently wrap to a small in-bounds address instead of trapping. The atomic wait fast path was the only Memory64 fast path that had not adopted baddpc, leaving the computed address unchecked before handing it to the slow path, which has no independent overflow check of its own.
Significance
A Memory64 module using memory.atomic.wait32 offset=8 against pointer 0xFFFF_FFFF_FFFF_FFF8n saw the engine wrap to address 0 and proceed in-bounds — a straightforward OOB-bypass primitive in a security-critical fast path.
Audit directions
- Other Memory64 instruction handlers in
InPlaceInterpreter64.asm. The atomic wait handlers appear to have been written separately from the main memory access fast paths and may not be the only ones that missedbaddpc. Grep for bareaddqused in pointer+offset computations across the file. - Atomic slow-path overflow assumptions.
ipint_slow_path_memory_atomic_wait32/64demonstrably had no overflow detection of its own — confirm it now performs an independent bounds check on its received address, given it cannot distinguish a wrapped address from a legitimate small pointer.