Medium CVSS 4.3 webkit UAF 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to an unexpected Safari crash
ComponentJSC Wasm
Bug ClassUAF
Tracker297958
Fix commitef9304e0e82b (WebKit/WebKit) +16/-0
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L
CISA KEVNot listed
CreditedGoogle Big Sleep
Disclosed2025-11-03

Background

Wasm reference type / TypeIndex
A reference-typed value carries a TypeIndex into the interned TypeDefinition registry describing its type.
TypeDefinition lifetime
TypeDefinitions are ref-counted and freed when nothing retains them; a bare TypeIndex does not keep one alive.
WasmTable / WasmGlobal
Long-lived wasm objects that can outlive the module which defined their element/value type.
getRef
The new accessor that returns a strong reference to a TypeIndex’s definition, or nullptr for primitives/invalid indices.

Root Cause Analysis

JavaScriptCore’s WebAssembly Table and Global store their element/value type as a Wasm::Type that, for reference types, carries a TypeIndex into the interned TypeInformation registry.

Pre-patch, WasmTable and WasmGlobal held that Wasm::Type (m_wasmType / m_type) WITHOUT retaining the underlying TypeDefinition. When the module that defined the type went away, the TypeDefinition the TypeIndex refers to could be freed while the Table/Global lived on, leaving m_type’s TypeIndex dangling; a later type-directed operation on the table/global dereferences the freed TypeDefinition — a use-after-free.

The fix retains the definition: WasmTable gains RefPtr<const TypeDefinition> m_wasmTypeDefinition and WasmGlobal gains RefPtr<const Wasm::TypeDefinition> m_typeDefinition, both initialized with a new TypeInformation::getRef(type.index) that returns the interned TypeDefinition (or nullptr when the index is a primitive type or invalid). Holding that RefPtr keeps the definition alive for the object’s lifetime, so the TypeIndex cannot dangle.

The restored invariant is that a Table/Global naming a reference type retains that type’s definition. (Note: this fix retains the directly-named definition; a later follow-up extended retention to the whole transitive type closure after finding nested types could still dangle.)

Key insight
WasmTable/WasmGlobal stored a reference type by TypeIndex without retaining its TypeDefinition, so the definition could be freed while the object lived on — a dangling-TypeIndex UAF; retaining it via TypeInformation::getRef fixes it.

Attack Path

  1. Create a typed table/global Build a wasm module with a table or global whose element/value type is a reference to a module-defined type (carrying a TypeIndex).
  2. Outlive the module Keep the exported table/global reachable while dropping references to the defining module so its TypeDefinitions can be freed.
  3. Free the definition Garbage collection reclaims the TypeDefinition the table/global’s Wasm::Type still indexes.
  4. Use-after-free A type-directed access to the table/global dereferences the dangling TypeIndex, corrupting memory in WebContent.

Impact Assessment

A use-after-free of a wasm TypeDefinition retained only by index in a Table/Global that outlives its module, reachable from crafted wasm in the WebContent process. GC timing is attacker-influenced, giving a groomable UAF; the observable is a crash. Confined to WebContent; rated medium. This is the root fix of a class later hardened (transitive retention) in a follow-up.

Changed Functions

FunctionChangeNotes
Table::Table / m_wasmTypeDefinition
Source/JavaScriptCore/wasm/WasmTable.cpp
modified Retains the table element type's TypeDefinition via RefPtr m_wasmTypeDefinition = TypeInformation::getRef(wasmType.index).
Global::Global / m_typeDefinition
Source/JavaScriptCore/wasm/WasmGlobal.h
modified Retains the global value type's TypeDefinition via RefPtr m_typeDefinition for both constructors.
TypeInformation::getRef
Source/JavaScriptCore/wasm/WasmTypeDefinitionInlines.h
added Returns a RefPtr<const TypeDefinition> for a TypeIndex (nullptr for primitive/invalid indices), used to retain reference-type definitions.

Files Changed

  • Source/JavaScriptCore/wasm/WasmGlobal.h
  • Source/JavaScriptCore/wasm/WasmTable.cpp
  • Source/JavaScriptCore/wasm/WasmTable.h
  • Source/JavaScriptCore/wasm/WasmTypeDefinition.h
  • Source/JavaScriptCore/wasm/WasmTypeDefinitionInlines.h

Audit Directions

  • Other bare TypeIndex holders
    grep wasm/ for Wasm::Type/TypeIndex members not paired with a retained TypeDefinition (tags, exceptions, caches).
  • Transitive retention
    Confirm follow-up work retains the full transitive type closure, since a directly-retained definition can still reference unretained nested types.
  • getRef adoption
    Ensure every place that stores a reference-typed Wasm::Type long-term uses getRef to retain it.

Original Bug Report

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