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 Bytecode
Bug ClassType Confusion
Tracker297662
Fix commit045fd8ec9237 (WebKit/WebKit) +50/-36
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
Creditedrheza (@ginggilBesel), shandikri working with Trend Micro Zero Day Initiative
Disclosed2025-11-03

Background

SpeculatedType
A bitset the DFG/FTL use to represent the possible types of a value and to guard specialized code.
SpecObjectOther
A generic ‘some other object’ speculated-type bucket that does not distinguish specific object kinds.
JSMapIterator / JSSetIterator
Distinct engine objects with different internal layouts backing Map/Set iteration.
Speculation check / type confusion
A JIT guard that, if too coarse, lets a value of the wrong concrete type pass and be misinterpreted.

Root Cause Analysis

The DFG/FTL JIT tracks value types with SpeculatedType bitsets and inserts speculation checks that guard type-specialized code. JSMapIterator and JSSetIterator objects were both mapped to the generic bucket SpecObjectOther rather than to distinct speculated types: speculationFromJSType returned SpecObjectOther for both iterator JSTypes, and speculateMapIteratorObject/speculateSetObject (in DFGSpeculativeJIT and FTLLowerDFGToB3) checked against SpecObjectOther. Because both iterators shared the same speculated type, the abstract interpreter and speculation checks could not distinguish a Map iterator from a Set iterator (nor from other SpecObjectOther objects): a node speculated to operate on a Map iterator would accept a Set iterator that passed the same SpecObjectOther check, so type-specialized code then accessed the wrong iterator’s internal layout – a type confusion between JSMapIterator and JSSetIterator. Operating on one iterator’s fields as if it were the other corrupts memory (advisory class UAF/crash).

The fix introduces distinct SpeculatedType bits SpecMapIteratorObject and SpecSetIteratorObject, returns them from speculationFromJSType for the respective JSTypes, and updates the speculation checks/UseKinds to use the specific type, so a Map-iterator speculation rejects a Set iterator and vice versa.

The restored invariant is that Map and Set iterators are distinct speculated types, so the JIT’s iterator type checks are precise.

Key insight
Map and Set iterators shared the SpecObjectOther speculated type, so the DFG/FTL couldn’t distinguish them and a speculation for one accepted the other – an iterator type confusion; giving each a distinct SpeculatedType makes the checks precise.

Attack Path

  1. Warm up iterator code in the JIT Run JS that uses Map and Set iterators so the DFG/FTL compiles iterator-specialized nodes speculating on iterator type.
  2. Confuse the speculation Pre-patch both iterators are SpecObjectOther, so a Map-iterator-speculated node accepts a Set iterator (or vice versa) that passes the same check.
  3. Access wrong iterator layout The type-specialized code treats one iterator kind as the other, reading/writing the wrong internal fields.
  4. Corrupt memory The iterator type confusion yields memory corruption in the WebContent process.

Impact Assessment

A JIT type confusion between Map and Set iterators (advisory class UAF): both mapped to SpecObjectOther, so speculation checks couldn’t tell them apart and iterator-specialized code accessed the wrong layout. That is a strong memory-corruption primitive reachable from ordinary Map/Set iterator use once JIT-compiled, in the WebContent process; the observable is a crash but the class is type confusion. Rated medium.

Changed Functions

FunctionChangeNotes
speculationFromJSType
Source/JavaScriptCore/bytecode/SpeculatedType.cpp
modified Returns distinct SpecMapIteratorObject / SpecSetIteratorObject for the Map/Set iterator JSTypes instead of the shared SpecObjectOther.
SpecMapIteratorObject / SpecSetIteratorObject bits
Source/JavaScriptCore/bytecode/SpeculatedType.h
modified Adds dedicated SpeculatedType bits so Map and Set iterators are distinguishable in speculation.
SpeculativeJIT::speculateMapIteratorObject / speculateSetObject
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
modified Speculation checks now use the specific iterator SpeculatedType, so the wrong iterator kind fails the check.
FTLLowerDFGToB3 iterator checks
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
modified FTL type checks for Map/Set iterators use the distinct speculated types (UseKinds updated in DFGUseKind.h).

Files Changed

  • JSTests/stress/map-set-iterator-speculated-types.js
  • Source/JavaScriptCore/bytecode/SpeculatedType.cpp
  • Source/JavaScriptCore/bytecode/SpeculatedType.h
  • Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
  • Source/JavaScriptCore/dfg/DFGUseKind.h
  • Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
  • Source/JavaScriptCore/runtime/JSType.h

Audit Directions

  • Other objects lumped into SpecObjectOther
    grep for speculationFromJSType returning SpecObjectOther for concrete JSTypes whose specialized code assumes a specific layout.
  • Iterator speculation coverage
    Audit DFG/FTL nodes handling Map/Set/Array iterators to ensure each checks the precise iterator SpeculatedType.
  • UseKind / speculateCellType precision
    Review speculateCellType call sites that pass a broad SpeculatedType with a specific JSType, which can admit the wrong concrete type.

Original Bug Report

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