[19] [JSC Wasm IPInt] Widen frame-size accumulator in IPInt::finalize
Rated High because the diff corrects a unit/scale mismatch in IPIntGenerator::finalize()'s computation of m_maxFrameSizeInV128; pre-fix, the stack-overflow probe used a value that diverged from actual frame usage, so a Wasm module with many locals could pass the probe while exceeding remaining native stack — an unchecked stack overflow in the worker thread.
IPIntGenerator::finalize() recomputes m_maxFrameSizeInV128 consistently with the runtime layout (LOCAL_SIZE = 16), ensuring the value matches the v128-slot interpretation used by the prologue.
Source/JavaScriptCore/wasm/wasmllint/IPIntGenerator.cpp
Stack-overflow check bypass via unit/scale miscomputation: the prologue stack probe and the actual frame allocation diverged under many-locals modules.
Patch Details
The frame-size accumulator is computed in v128 units consistently with IPIntLocal's 16-byte slot. The runtime prologue stack-check now sees a value that matches actual usage.
Background
The IPInt header declares IPIntLocal as 16 bytes (LOCAL_SIZE = 16); each local occupies one v128 in the IPInt frame. IPIntGenerator::finalize() is the final compilation step for the IPInt tier and computes the per-function frame size used by the prologue stack-overflow check.
Analysis
Pre-fix, the finalize step computed m_maxFrameSizeInV128 in a unit that did not match the runtime layout. If the value was computed in bytes (or in 8-byte units) but interpreted as v128 slots — or vice versa — the prologue probe diverged from actual frame usage.
The test sweeps 8000–35000 i64 locals × 16 B = 128 KB–560 KB of frame. The divergence is large enough that the probe passes while the actual usage exceeds the remaining native stack — an unchecked stack overflow in the worker thread. The downstream primitive is stack-blown memory access in a Wasm-compiled function, including overwrite of saved registers and return addresses below the stack guard.
This weakens the IPInt stack-overflow invariant for many-locals Wasm modules.
Audit directions
- Every JIT-tier frame-size computation for unit/scale consistency with the prologue probe. BBQ, OMG, and DFG inlining of Wasm should be audited similarly.
- Stack-check arithmetic on attacker-controlled inputs — local counts, parameter counts, max stack depth.
IPIntLocalsize assumptions across the IPInt source.