
CVE-2026-2766, но с wasm
Статус: подтверждённый PoC краха с продемонстрированным перехватом потока управления
(краш pc = отравление освобождённой ячейки 0xcdcdcdcdcdcdcdcd под отладочной
оболочкой — движок переходит по указателю, считанному из освобождённого ICScript).
Оставшаяся работа: контролировать переиспользуемые байты. См.
research/README.md.
Цепочка семейства WasmBlazeFox на баге 2026 года: CVE-2026-2766, "JIT miscompilation / use-after-free in the JavaScript Engine: JIT component", исправлен в Firefox 148 (MFSA 2026-13). Финальная цель та же, что и в CVE-2024-29943-but-with-wasm: превратить примитив в контроль над указателем кода и нацелить его на страницу WASM JIT, полную констант шелл-кода.
Из комментариев к собственному регрессионному тесту Mozilla (bug 2013583, тест добавлен в
hg 457b68097f81) и SMDOC ICScript Lifetimes в js/src/jit/JitScript.h:
removeInlinedChildICScriptinlinedChildren_inlinedScripts_InliningRootCallInlinedFunctiongczeal(14, 1), т.е. ZealCompactValue при каждой
аллокации) перемещает/эвакуирует осиротевший ICScript, пока устаревшая цепочка
стабов сохраняет старый адрес.0xe5, что даёт очень читаемый краш.Уязвимая сборка: mozilla-central rev b3663be61a1a (nightly от 2026-01-15;
исправление попало между 2026-01-15 и 2026-02-09 — nightly от 09 февраля
выживает). Оболочка: Taskcluster linux64-fuzzing-asan-opt jsshell для этой
ревизии (нужна для gczeal; release-opt оболочки её лишены).
./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
Разыменование происходит в коде baseline JIT при обходе устаревшей цепочки стабов: контроль над переиспользуемой ячейкой = контроль над полями ICEntry/стаба, которым доверяет baseline, включая указатель кода стаба, на который он переходит.
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)
См. research/README.md для полного
журнала вооружения. Краткое изложение текущего состояния:
TrailingArray) — в принципе переиспользуемого через spray с буферами
соответствующих size-классов.new Ctor(flag), без точки обратного вызова в JS между
ними; наивные spray либо промахиваются мимо окна (reclaim1/2), либо
вымывают состояние IC штормом zeal GC (reclaim3). Устаревшая цепочка
действительно выживает после одного обычного gc() (purge_check).Сам этап WASM уже построен и продемонстрирован в CVE-2024-29943-but-with-wasm; лишь смещения объектной модели нужно заново вывести для этой сборки эпохи FF149.
poc.js — регрессионный тест Mozilla (bug 2013583), проверено, что он
вызывает краш ASAN jsshell от 2026-01-15, как показано выше.457b68097f81