CVE-2025-31273
Overview
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.
Attack Path
- Insert a key with side effects Add to a Map/Set a key whose normalization (valueOf/toString or proxy) runs attacker JS.
- Reallocate during normalization From that callback, cause the table to rehash/reallocate (or trigger GC), invalidating the pre-computed candidate storage and indices.
- Write at a stale index The add continues using the captured capacity/newEntry index into the now-freed/moved storage.
- Corrupt memory The stale-index write corrupts heap memory in the WebContent process.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
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 effectsAudit OrderedHashTableHelper for other places that capture storage pointers/indices before a call that can rehash, GC, or run user code.
- Side-effecting key normalizationGrep Map/Set/WeakMap operations for cached candidate/capacity values used across normalizeMapKey / hashValue calls that may re-enter.