
Воспроизведение уязвимости use-after-free в WebAssembly в движке JavaScript от Mozilla, демонстрирующее детерминированное состояние гонки и предоставляющее контролируемое доказательство концепции.
Не самое изящное воспроизведение. Базовая настройка потребовала некоторых доработок.
Mozilla описывает эту проблему как use-after-free в WebAssembly. Публичный фикс
9823b5c86ffa сохраняет точный перехватывающий wasm::Code живым в JitActivation.
Тест выполняет межэкземплярный хвостовой вызов с неверной сигнатурой. Хук unwind в Debugger очищает последнюю ссылку на цель в таблице и принудительно запускает сборку мусора со сжатием, пока движок обрабатывает ловушку. Перед входом в хвостовой вызов Wasm вызывает обычный JavaScript-импорт, который печатает маркер.
9b564f641a42: статус 139 (SIGSEGV).9823b5c86ffa: печатает PASS: trap handled after target release и
завершается с кодом 0.poc-controlled.js расширяет выделение общего стаба цели 144
импортами. Его устаревшее продолжение throw приземляется внутри одной из четырёх
исполняемых страниц. Заранее созданный носитель ленивого тиринга встраивает 6 000 уникальных SIMD-констант в
четырёхстраничный оптимизированный сегмент кода. Во время unwind исключения GC освобождает
цель, и синхронный тиринг повторно использует эту дыру. Сисколл-дорожка каждые
64 байта печатает UAF NACHOS и вызывает exit_group(0).
Запуск:
js --wasm-compiler=baseline+ion \
--setpref=wasm_lazy_tiering_level=9 \
--setpref=wasm_lazy_tiering_synchronous=true \
--more-compartments poc-controlled.js
Наблюдаемая надёжность на собранной из исходников Linux x86-64 оболочке до фикса: 3/3
запуска напечатали маркер и завершились с кодом 0. Соответствующая оболочка с фиксом вызывает обычную
RuntimeError: indirect call signature mismatch и не печатает его.
Контролируемый PoC использует только shell-функции Debugger и GC, чтобы сделать гонку детерминированной. Он устанавливает нативный контроль в jsshell, а не доставку с веб-страницы или побег из песочницы контента Firefox.
Запуск с эквивалентной отладочной оболочкой:
js --wasm-compiler=baseline --more-compartments poc.js
Это свидетельство регрессии времени жизни, а не примитив памяти или эксплойт. Маркер появляется в обеих сборках и не является результатом UAF.