Medium CVSS 4.3 webkit Type Confusion 🔧 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 ClassType Confusion
Tracker317349
Fix commit5b76326e8fc9 (WebKit/WebKit) +162/-12
CWECWE-20 (Improper input validation)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L
CISA KEVNot listed
CreditedJosef Korbel
Disclosed2026-08-17

Background

ref.test / ref.cast (WASM GC)
Instructions that test/cast a reference to a target heap type, with an allowNull flag deciding whether null matches.
In-Place Interpreter (IPInt)
JSC’s low-level WASM interpreter driven by metadata; it must read instruction operands from validated metadata, not ad-hoc bytecode offsets.
RefTestCastMetadata
The per-instruction metadata for ref cast/test; it must carry allowNull so the interpreter uses the correct semantics.

Root Cause Analysis

This fixes a WebAssembly GC type-confusion in the In-Place Interpreter (IPInt) where the ‘allow null’ flag for ref.test/ref.cast/br_on_cast was read from the wrong place. ref.test/ref.cast (and br_on_cast/br_on_cast_fail) check whether a reference matches a target heap type, parameterized by allowNull (whether a null reference satisfies the cast).

Pre-patch, the IPInt generator (addRefTest/addRefCast/addBranchCast) IGNORED the allowNull argument and did not store it in RefTestCastMetadata, and the interpreter (InPlaceInterpreter64.asm) instead tried to recover the null bit directly from the bytecode stream — loadb 2[PC] then rshifti 1 (bit 1) — a fragile, incorrect read of a flags byte at a fixed PC offset. As a result the effective allowNull used at runtime could be wrong, so a null reference could be accepted by a non-nullable cast (or a nullable cast mis-evaluated), yielding a value of the wrong nullability/type where a valid typed reference is expected — a type confusion.

The fix threads allowNull properly: RefTestCastMetadata gains a uint8_t allowNull field, the generator stores static_cast<uint8_t>(allowNull) for ref.test/ref.cast/br_on_cast, and the interpreter loads it from validated metadata (loadb IPInt::RefTestCastMetadata::allowNull[MC]) instead of the ad-hoc 2[PC] bit-shift.

The restored invariant is that the null-allowed semantics of a ref cast/test come from the validated metadata emitted by the generator, not a mis-derived bytecode byte.

Key insight
The IPInt interpreter reconstructed the ref-cast allowNull flag from a fixed bytecode offset (loadb 2[PC]) instead of validated metadata, so casts could use the wrong nullability; storing allowNull in RefTestCastMetadata and reading it from there fixes the type confusion.

Attack Path

  1. Run a ref.cast/ref.test in IPInt Execute WASM GC casts (ref.cast/ref.test/br_on_cast) under the In-Place Interpreter.
  2. Exploit the mis-read null flag Because the interpreter derived allowNull from the wrong bytecode byte, arrange a cast whose effective nullability is wrong.
  3. Slip a null / wrong-typed ref through A null (or wrong-nullability) reference is accepted by a cast that should reject it, or a non-null cast is mis-evaluated.
  4. Type confusion The mistyped reference is used as a valid typed reference, a memory-safety violation crashing the WebContent process.

Impact Assessment

A WebAssembly GC type-confusion in the WebContent process, reachable from crafted WASM using ref.cast/ref.test. Mis-evaluating nullability lets a null or wrong-typed reference pass a cast, producing a mistyped reference — a memory-safety primitive the advisory rates as a crash.

Changed Functions

FunctionChangeNotes
IPIntGenerator::addRefTest / addRefCast / addBranchCast
Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp
modified Store the allowNull flag into RefTestCastMetadata instead of ignoring it.
RefTestCastMetadata
Source/JavaScriptCore/wasm/WasmIPIntGenerator.h
modified Adds a uint8_t allowNull field carrying the validated null-allowed semantics.
ipintOp _br_on_cast / _br_on_cast_fail (and ref.test/cast)
Source/JavaScriptCore/llint/InPlaceInterpreter64.asm
modified Reads allowNull from RefTestCastMetadata (loadb ...::allowNull[MC]) instead of the fragile loadb 2[PC]/rshifti-1 bytecode bit.

Files Changed

  • JSTests/wasm/stress/br-on-cast-fail-overlong-leb128.js
  • JSTests/wasm/stress/br-on-cast-overlong-leb128.js
  • Source/JavaScriptCore/llint/InPlaceInterpreter64.asm
  • Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp
  • Source/JavaScriptCore/wasm/WasmIPIntGenerator.h

Audit Directions

  • Operand provenance in IPInt
    Audit InPlaceInterpreter*.asm for operands recovered via loadb N[PC]/bit-shifts rather than named metadata fields; each is a chance to read the wrong byte.
  • Generator/interpreter metadata parity
    Grep IPIntGenerator for instruction args (flags) that are accepted but not stored into the corresponding *Metadata the interpreter reads.

Original Bug Report

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