Medium CVSS 8.8 webkit OOB 🔧 Commit mapped

Overview

Medium
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to memory corruption
ComponentJSC Runtime
Bug ClassOOB
Tracker293579
Fix commita05032c69610 (WebKit/WebKit) +6/-6
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
CreditedYuhao Hu, Yan Kang, Chenggang Wu, and Xiaojie Wei
Disclosed2025-07-29

Background

OrderedHashTable
The insertion-ordered hash table backing JavaScript Map and Set in JSC.
normalizeMapKey
Normalizes a key (e.g. -0 to 0); for object/proxy keys it can invoke user code with side effects.
Rehash / reallocation
Growing the table moves its storage; indices captured before a reallocation become stale.

Root Cause Analysis

This fixes a memory-corruption bug in JavaScriptCore’s OrderedHashTable (backing Map/Set) where storage-derived indices were computed before a JS-observable side effect that can reallocate the storage. In add(), after expandIfNeeded returns the candidate storage, the pre-patch code immediately captured capacity, newEntry = usedCapacity(candidate), the new entry’s key index, and called incrementAliveEntryCount(candidate) — and only THEN, for the first alive entry, called normalizeMapKey(key). normalizeMapKey can run arbitrary JS (via valueOf/toString or a proxy) which may re-enter the engine, allocate, trigger GC, or cause the table to rehash/reallocate, invalidating the previously captured candidate/capacity/newEntry index. The subsequent write then uses a stale index into freed or moved storage — memory corruption.

The fix reorders the operations: it performs the firstAliveEntry normalizeMapKey step first, and only afterward computes capacity/newEntry/newEntryKeyIndex and increments the alive count from the current candidate state.

The restored invariant is that storage-derived indices and counters are computed after any step that can reallocate the storage.

Key insight
The add path cached storage capacity and the new-entry index and bumped the live count before normalizeMapKey, which can reallocate the table — so the write landed at a stale index; reordering the bookkeeping after the side effect fixes it.

Attack Path

  1. Insert a key with side effects Add to a Map/Set a key whose normalization (valueOf/toString or proxy) runs attacker JS.
  2. Reallocate during normalization From that callback, cause the table to rehash/reallocate (or trigger GC), invalidating the pre-computed candidate storage and indices.
  3. Write at a stale index The add continues using the captured capacity/newEntry index into the now-freed/moved storage.
  4. Corrupt memory The stale-index write corrupts heap memory in the WebContent process.

Impact Assessment

A memory-corruption primitive in the WebContent process reachable from ordinary Map/Set usage with a side-effecting key. Stale-index writes into reallocated hash-table storage are controllable with grooming; the advisory rates it memory corruption.

Changed Functions

FunctionChangeNotes
OrderedHashTable add (index bookkeeping)
Source/JavaScriptCore/runtime/OrderedHashTableHelper.h
modified Moves capacity/newEntry/newEntryKeyIndex computation and incrementAliveEntryCount to AFTER the normalizeMapKey side effect, so indices reflect the possibly-reallocated storage.

Files Changed

  • Source/JavaScriptCore/runtime/OrderedHashTableHelper.h

Audit Directions

  • Same file: order of side effects
    Audit OrderedHashTableHelper for other places that capture storage pointers/indices before a call that can rehash, GC, or run user code.
  • Side-effecting key normalization
    Grep Map/Set/WeakMap operations for cached candidate/capacity values used across normalizeMapKey / hashValue calls that may re-enter.

Original Bug Report

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