
CVE-2026-2766, mas com wasm
Status: PoC de crash validado com sequestro de fluxo de controle demonstrado
(crash pc = poison de célula liberada 0xcdcdcdcdcdcdcdcd sob o shell de
debug — o engine salta para um ponteiro lido do ICScript liberado).
Trabalho restante: controlar os bytes recuperados. Veja
research/README.md.
Uma cadeia da família WasmBlazeFox sobre um bug de 2026: CVE-2026-2766, "JIT miscompilation / use-after-free no JavaScript Engine: componente JIT", corrigido no Firefox 148 (MFSA 2026-13). O desfecho é o mesmo de CVE-2024-29943-but-with-wasm: transformar a primitiva em controle de um ponteiro de código, e apontá-lo para uma página JIT de WASM cheia de constantes de shellcode.
A partir dos próprios comentários do teste de regressão da Mozilla (bug 2013583,
teste integrado em hg 457b68097f81) e do SMDOC ICScript Lifetimes em
js/src/jit/JitScript.h:
removeInlinedChildICScriptinlinedChildren_inlinedScripts_InliningRootCallInlinedFunctiongczeal(14, 1), ou seja, ZealCompactValue a cada
alocação) move/evacua o ICScript órfão enquanto a cadeia de stubs obsoleta
mantém o endereço antigo.0xe5, gerando um crash bem legível.Build vulnerável: mozilla-central rev b3663be61a1a (nightly de 2026-01-15;
a correção foi integrada entre 2026-01-15 e 2026-02-09 — a nightly de 09-fev
sobrevive). Shell: jsshell linux64-fuzzing-asan-opt do Taskcluster para essa
rev (necessário para gczeal; shells release-opt não o possuem).
./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
A desreferência ocorre em código JIT baseline percorrendo a cadeia de stubs obsoleta: controle da célula recuperada = controle dos campos ICEntry/stub em que o baseline confia, incluindo o ponteiro de código do stub para o qual ele salta.
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)
Veja research/README.md para o log completo de
weaponização. Resumo do estado atual:
TrailingArray) — recuperável por spray em princípio com buffers de
size-class.new Ctor(flag), sem ponto de callback JS entre eles; sprays ingênuos
ou perdem a janela (reclaim1/2) ou agitam o estado IC com uma tempestade
de GC zeal (reclaim3). A cadeia obsoleta sobrevive a um único gc()
simples (purge_check).O estágio WASM em si já está construído e demonstrado em CVE-2024-29943-but-with-wasm; apenas os offsets do object-model precisam ser re-derivados para este build da era FF149.
poc.js — teste de regressão da Mozilla (bug 2013583), verificado como
causador de crash no jsshell ASAN de 2026-01-15 conforme mostrado acima.457b68097f81