
CVE-2026-2766, pero con wasm
Estado: PoC de fallo validado con secuestro de flujo de control demostrado
(pc del fallo = veneno de celda liberada 0xcdcdcdcdcdcdcdcd bajo el shell
de depuración — el motor salta a un puntero leído del ICScript liberado).
Trabajo restante: controlar los bytes reclamados. Véase
research/README.md.
Una cadena de la familia WasmBlazeFox sobre un fallo de 2026: CVE-2026-2766, "JIT miscompilation / use-after-free in the JavaScript Engine: JIT component", corregido en Firefox 148 (MFSA 2026-13). El objetivo final es el mismo que CVE-2024-29943-but-with-wasm: convertir la primitiva en control de un puntero de código, y apuntarlo a una página JIT de WASM llena de constantes de shellcode.
De los propios comentarios de la prueba de regresión de Mozilla (bug 2013583, prueba
incluida en hg 457b68097f81) y del SMDOC ICScript Lifetimes en js/src/jit/JitScript.h:
removeInlinedChild → el ICScript del hijo se elimina de
inlinedChildren_ pero sigue siendo referenciado por el vector
inlinedScripts_ del InliningRoot — y, de forma fatal, por el stub obsoleto
CallInlinedFunction que aún permanece en la cadena IC del llamador.gczeal(14, 1), es decir, ZealCompactValue en cada
asignación) mueve/evacúa el ICScript huérfano mientras la cadena de stubs obsoleta
conserva la dirección antigua.0xe5, dando un fallo muy legible.Compilación vulnerable: mozilla-central rev b3663be61a1a (nightly del 2026-01-15;
la corrección se incluyó entre el 2026-01-15 y el 2026-02-09 — la nightly del 09-feb
sobrevive). Shell: jsshell de Taskcluster linux64-fuzzing-asan-opt para esa
rev (necesario para gczeal; los shells release-opt carecen de él).
./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
La desreferencia ocurre en código JIT baseline recorriendo la cadena de stubs obsoleta: control de la celda reclamada = control de los campos ICEntry/stub en los que confía el baseline, incluido el puntero de código del stub al que 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)
Véase research/README.md para el registro completo
de weaponización. Resumen del estado actual:
TrailingArray) — reclamable mediante spray en principio con búferes
clasificados por tamaño.new Ctor(flag), sin ningún punto de callback de JS entre ellos; los
sprays ingenuos o bien pierden la ventana (reclaim1/2) o desbaratan el estado
IC con una tormenta de GC zeal (reclaim3). La cadena obsoleta sí sobrevive a
un único gc() simple (purge_check).La etapa WASM en sí ya está construida y demostrada en CVE-2024-29943-but-with-wasm; solo hay que volver a derivar los offsets del modelo de objetos para esta compilación de la era FF149.
poc.js — prueba de regresión de Mozilla (bug 2013583), verificada para hacer
fallar el jsshell ASAN del 2026-01-15 como se muestra arriba.457b68097f81