
CVE-2026-2766, but with wasm
Status: validated crash PoC with demonstrated control-flow hijack
(crash pc = freed-cell poison 0xcdcdcdcdcdcdcdcd under the debug
shell — the engine jumps to a pointer read out of the freed ICScript).
Remaining work: control the reclaimed bytes. See
research/README.md.
A WasmBlazeFox-family chain on a 2026 bug: CVE-2026-2766, "JIT miscompilation / use-after-free in the JavaScript Engine: JIT component", fixed in Firefox 148 (MFSA 2026-13). The endgame is the same as CVE-2024-29943-but-with-wasm: turn the primitive into control of a code pointer, and aim it at a WASM JIT page full of shellcode constants.
From Mozilla's own regression test comments (bug 2013583, test landed in
hg 457b68097f81) and the ICScript Lifetimes SMDOC in js/src/jit/JitScript.h:
removeInlinedChild → the child's is removed from
but is still referenced by the 's
vector — and, fatally, by the stale
stub still sitting in the caller's IC chain.ICScriptinlinedChildren_InliningRootinlinedScripts_CallInlinedFunctiongczeal(14, 1), i.e. ZealCompactValue every
allocation) moves/evacuates the orphaned ICScript while the stale stub
chain keeps the old address.0xe5, giving a very readable crash.Vulnerable build: mozilla-central rev b3663be61a1a (2026-01-15 nightly;
the fix landed between 2026-01-15 and 2026-02-09 — the Feb-09 nightly
survives). Shell: Taskcluster linux64-fuzzing-asan-opt jsshell for that
rev (needed for gczeal; release-opt shells lack it).
./js --ion-warmup-threshold=100000 poc.js
== ERROR: AddressSanitizer: SEGV on unknown address 0xe5e5e5e5e5e5e5e5
The signal is caused by a READ memory access.
#0-#3 <unknown module> <- baseline JIT code
#4 EnterJit / MaybeEnterJit <- js/src/jit/Jit.cpp
#10 js::jit::DoCallFallback <- BaselineIC.cpp (the stale IC chain)
rdi = 0xe5e5e5e5e5e5e5e5 <- the freed ICScript
The dereference happens in baseline JIT code walking the stale stub chain: control of the reclaimed cell = control of the ICEntry/stub fields the baseline trusts, including the stub code pointer it jumps to.
orphaned ICScript (this PoC)
-> compacting GC moves it; stale chain keeps old address
-> reclaim the old cell with controlled bytes (size-class spray)
-> baseline reads fake ICEntry -> fake ICStub -> fake code_ pointer
-> jump into the WASM JIT page shellcode (f64.const immediates,
FuncExport entry-offset overwrite — see the 2024-29943 repo)
See research/README.md for the full
weaponization log. Summary of where it stands:
TrailingArray) ICScript —
spray-reclaimable in principle with size-classed buffers.new Ctor(flag) call, with no JS callback point between them; naive
sprays either miss the window (reclaim1/2) or churn the IC state away
with a zeal GC storm (reclaim3). The stale chain does survive a single
plain gc() (purge_check).The WASM stage itself is already built and demonstrated in CVE-2024-29943-but-with-wasm; only the object-model offsets need re-deriving for this FF149-era build.
poc.js — Mozilla's regression test (bug 2013583), verified to crash the
2026-01-15 ASAN jsshell as shown above.457b68097f81