CVE-2025-31277
Overview
Background
- Having a bad time
- JSC state entered when Array/Object.prototype gets indexed properties; fast indexed array storage becomes unsafe and arrays must use ArrayStorage.
- ArrayWithContiguous
- A fast array indexing type assuming dense storage and no interfering prototype accessors.
- RegExp matches array
- A consumer that uses the fast contiguous-array creation path, exercised by the exploit.
Root Cause Analysis
This fixes a type-confusion / memory-corruption bug where JavaScriptCore’s fast contiguous-array creation ignored the global object’s ‘having a bad time’ state. When Array.prototype or Object.prototype gains indexed properties (e.g. an indexed getter/setter), JSC enters isHavingABadTime(): fast contiguous/indexed array storage is no longer safe because indexed access must consult the prototype chain, so arrays must use the slower ArrayStorage path. tryCreateContiguousArrayWithPattern is a fast path (used for example when building RegExp matches arrays) that constructs an ArrayWithContiguous array directly. Pre-patch it checked length limits but did not check isHavingABadTime(), so during a bad time it still produced a contiguous-indexing array whose storage assumptions conflict with the prototype’s indexed accessors — later indexed reads/writes treat attacker-influenced state as fast contiguous storage, a type confusion leading to memory corruption.
The fix adds if (globalObject->isHavingABadTime()) return nullptr; so the caller falls back to the safe array-creation path.
The restored invariant is that fast contiguous-array creation is disabled whenever the global object is having a bad time. The regression test installs an indexed accessor (entering a bad time) and creates a RegExp matches array, then writes a large index.
Attack Path
- Enter 'having a bad time' Define an indexed property (getter/setter) on Array.prototype or Object.prototype so the global object enters isHavingABadTime().
- Trigger fast array creation Cause a RegExp match (or other consumer) to call tryCreateContiguousArrayWithPattern, which pre-patch ignored the bad-time state.
- Obtain an inconsistent array Receive an ArrayWithContiguous array whose storage violates the bad-time invariant.
- Corrupt memory Indexed access on the array is type-confused against the prototype’s indexed accessors, yielding memory corruption in WebContent.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
tryCreateContiguousArrayWithPatternSource/JavaScriptCore/runtime/JSGlobalObjectInlines.h |
modified | Returns nullptr when globalObject->isHavingABadTime(), forcing the safe (ArrayStorage) path instead of building a contiguous-indexing array during a bad time. |
Files Changed
JSTests/stress/regexp-matches-array-should-respect-have-a-bad-time.jsSource/JavaScriptCore/runtime/JSGlobalObjectInlines.h
Audit Directions
- Fast array-creation pathsGrep JSGlobalObjectInlines and array-allocation helpers for tryCreate*Array / originalArrayStructureForIndexingType uses that omit an isHavingABadTime() guard.
- Consumers of fast patternsAudit RegExp/spread/Array builtins that build arrays via fast patterns to confirm they honor the bad-time state.