Critical CVSS 8.8 webkit OOB 🔧 Commit mapped

Overview

Critical
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to arbitrary code execution
ComponentJSC Wasm
Bug ClassOOB
Tracker272106
Fix commit1e58c9386ed9 (WebKit/WebKit)
CWECWE-119 (Buffer bounds error)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedNan Wang (@eternalsakura13) of 360 Vulnerability Research Institute
Disclosed2024-05-13

Background

OMG / B3IRGenerator
JSC’s optimizing wasm tier and its B3 IR generator, which can inline direct calls between wasm functions.
Call-site index
An index identifying a call site used to look up exception-handling metadata during unwinding.
hasExceptionHandlers
Per-function state indicating whether a wasm function contains try/catch handlers, needed to emit correct EH metadata when inlined.
CalleeGroup
The per-module registry of compiled wasm callees, used here to look up an inlinee’s real exception-handler state.

Root Cause Analysis

When JavaScriptCore’s optimizing wasm compiler (OMG/B3) inlines a direct call, the inlinee’s B3IRGenerator must know whether the inlined function contains exception handlers, because that determines the call-site index metadata emitted for exception dispatch.

Pre-patch, the inlining constructor B3IRGenerator(parentCaller, rootCaller, functionIndex, returnContinuation, args) hardcoded m_hasExceptionHandlers(false) and never consulted the actual inlinee, and emitInlineDirectCall used a shortcut bool mayHaveExceptionHandlers = !m_hasExceptionHandlers || m_hasExceptionHandlers.value(); to decide whether to emit a real call-site index or PatchpointExceptionHandle::s_invalidCallSiteIndex. So when a function that does have exception handlers was inlined, the generator believed it had none and emitted invalid/placeholder call-site indices for the inlined region. If an exception was then thrown across that inlined frame, the unwinder resolved the wrong (invalid) call-site index and used incorrect exception-handling metadata — an out-of-bounds / type-confused read of handler tables that WebKit’s advisory describes as leading to arbitrary code execution.

The fix threads the module’s CalleeGroup& into the generators and, in emitInlineDirectCall, looks up the real inlinee (wasmEntrypointCalleeFromFunctionIndexSpace(...).hasExceptionHandlers()) to pass a correct std::optional<bool> hasExceptionHandlers into the inlinee generator; it also propagates the parent’s exception-handler state (if (parentCaller.m_hasExceptionHandlers && *parentCaller.m_hasExceptionHandlers) m_hasExceptionHandlers = { true }), removes the invalid-call-site-index shortcut (always emitting proper indices), and extends PatchpointExceptionHandle to carry a callSiteIndex.

The restored invariant is that inlined wasm frames always carry accurate has-exception-handlers state and valid call-site indices, so exception unwinding indexes the correct handler metadata.

Key insight
Wasm call inlining hardcoded the inlinee as having no exception handlers and emitted invalid call-site indices, so an exception thrown through an inlined EH-bearing function dispatched on wrong metadata; propagating the real hasExceptionHandlers state and valid call-site indices fixes it.

Attack Path

  1. Craft a wasm module with EH + inlining Build a module where a small function containing exception handlers is a hot inlining target of a caller compiled by OMG/B3.
  2. Force optimizing compilation + inlining Warm the functions so OMG inlines the EH-bearing callee via emitInlineDirectCall, which pre-patch records the inlinee as having no exception handlers.
  3. Emit invalid call-site metadata The inlined region is compiled with placeholder/invalid call-site indices because m_hasExceptionHandlers was false.
  4. Throw across the inlined frame Trigger an exception in the inlined callee so the unwinder resolves the wrong call-site index and reads incorrect exception-handler metadata.
  5. Corrupt / hijack control flow The mismatched handler metadata yields an out-of-bounds/type-confused dispatch that the advisory rates as arbitrary code execution in WebContent.

Impact Assessment

A JIT exception-metadata correctness bug: inlining an exception-handler-bearing wasm function while recording it as having none produced invalid call-site indices, so throwing across the inlined frame dispatches on wrong handler metadata. This is a powerful primitive — the advisory rates it arbitrary code execution — reachable from a crafted wasm module, though it requires shaping inlining and an exception. Confined to the WebContent process. Rated critical.

Changed Functions

FunctionChangeNotes
B3IRGenerator inlining constructor
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
modified Takes CalleeGroup& and an explicit std::optional<bool> hasExceptionHandlers, initializes m_hasExceptionHandlers from it, and inherits the parent's true exception-handler state instead of hardcoding false.
B3IRGenerator::emitInlineDirectCall
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
modified Looks up the real inlinee via m_calleeGroup.wasmEntrypointCalleeFromFunctionIndexSpace(...).hasExceptionHandlers() and always emits valid call-site indices (removes the s_invalidCallSiteIndex shortcut).
parseAndCompileB3
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
modified Signature gains CalleeGroup& so the generator can resolve inlinee callees; OMGPlan/OSREntryPlan updated to pass m_calleeGroup.
PatchpointExceptionHandle
Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h
modified Now carries a callSiteIndex alongside hasExceptionHandlers so exception patchpoints reference the correct site.

Audit Directions

  • Other inlining-propagated state
    Audit B3IRGenerator’s inlining constructor for other fields defaulted/hardcoded rather than derived from the inlinee (stack checks, memory mode, tier-up).
  • Call-site index emission
    grep wasm/ for s_invalidCallSiteIndex and mayHaveExceptionHandlers to find other places that substitute placeholder call-site indices based on possibly-wrong EH state.
  • hasExceptionHandlers plumbing
    Trace hasExceptionHandlers/CalleeGroup::hasExceptionHandlers through OMG/OSR/BBQ compilation to ensure every inlined or tiered path uses the callee’s true value.

Original Bug Report

The reporter's bug is still restricted on the tracker.