[3] JSC PutByVal IC IndexingHeader Corruption via Non-String Primitive Key Transition
Severity: High | Component: JSC Inline Cache | 4731033
Rated High because the observable effect is corruption of IndexingHeader metadata for typed array views reachable from web content via a straightforward trigger (resizable ArrayBuffer + primitive key assignment), and the projected primitive — OOB access on the ArrayBuffer backing store — is consistent with the zeroed bounds metadata and the commit message's description of "incorrect" subsequent indexed accesses, though the exact behavior of downstream bounds checks with zeroed metadata is unverified.
Patch Details
The patch adds a new putByValNonStringPrimitiveKeyTransitionOutOfLineHandlerImpl template function in InlineCacheCompiler.cpp that calls operationReallocateButterflyAndTransition to properly handle butterfly reallocation for objects with an IndexingHeader. The DEFINE_CONSTANT_KEY_PUTBYVAL_HANDLERS macro is updated so that the TransitionReallocatingOutOfLineHandler entry for non-string primitive keys (undefined, null, true, false) dispatches to this new handler instead of the inline allocation path that zero-fills the butterfly without preserving the existing IndexingHeader.
Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp
+template<NonStringPrimitiveKeyType keyType>
+static MacroAssemblerCodeRef<JITThunkPtrTag> putByValNonStringPrimitiveKeyTransitionOutOfLineHandlerImpl(VM& vm)
+{
+ CCallHelpers jit;
+ ...
+ fallThrough.append(emitNonStringPrimitiveKeyCheck<keyType>(jit, propertyJSR));
+ fallThrough.append(InlineCacheCompiler::emitDataICCheckStructure(jit, baseJSR.payloadGPR(), scratch1GPR));
+ ...
+ jit.setupArguments<decltype(operationReallocateButterflyAndTransition)>(CCallHelpers::TrustedImmPtr(&vm), baseJSR.payloadGPR(), GPRInfo::handlerGPR, valueJSR);
+ jit.callOperation<OperationPtrTag>(operationReallocateButterflyAndTransition);
+ ...
+}
MacroAssemblerCodeRef<JITThunkPtrTag> putByValWith##KeyName##KeyTransitionReallocatingOutOfLineHandler(VM& vm) \
- { return putByValNonStringPrimitiveKeyTransitionHandlerImpl<true, false, NonStringPrimitiveKeyType::keyType>(vm); }
+ { return putByValNonStringPrimitiveKeyTransitionOutOfLineHandlerImpl<NonStringPrimitiveKeyType::keyType>(vm); }
JSTests/stress/resizable-typed-array-non-string-primitive-key-transition.js
+for (let i = 0; i < 1000; i++) {
+ const buf = new ArrayBuffer(7, { maxByteLength: 3378 });
+ const ta = new Int8Array(buf);
+ ta[undefined] = 42;
+ ta[0];
+}
IC transition handler dispatches to an inline butterfly allocator that destroys the IndexingHeader required by ArrayBuffer views.
Background
JSC's inline cache (IC) system generates specialized machine-code stubs for property operations, keyed on object structure. When a property store causes a structure transition that requires butterfly reallocation, the IC must allocate a new butterfly and copy data from the old one. The butterfly is JSC's out-of-line property and indexed-element storage — a contiguous memory region attached to a JSObject. For objects with an IndexingHeader — such as typed array views backed by ArrayBuffers — the butterfly's header region stores metadata (like byte length for resizable typed arrays) that subsequent indexed element accesses depend on for bounds checking.
operationReallocateButterflyAndTransition is the runtime function that properly handles butterfly reallocation including IndexingHeader preservation. Commit 310410@main added PutByVal IC support for non-string primitive keys (undefined, null, true, false), which are converted to string property names (e.g., "undefined") and stored as named properties, potentially triggering structure transitions that require butterfly reallocation.
Analysis
The non-string primitive key PutByVal IC (added in 310410@main) had a TransitionReallocatingOutOfLineHandler that incorrectly dispatched to the inline allocation handler (putByValNonStringPrimitiveKeyTransitionHandlerImpl<true, false, keyType>). This handler zero-fills the newly allocated butterfly without copying the existing IndexingHeader from the old butterfly (as strongly inferred from the fix pattern — the old handler's body is not shown in the diff). For objects with an IndexingHeader — specifically ArrayBuffer views like typed arrays — this IndexingHeader contains critical metadata (e.g., byte length for resizable typed arrays). After the IC fires and the butterfly is reallocated with a zeroed IndexingHeader, subsequent indexed accesses to the typed array operate against corrupted metadata.
The string-key handlers already had the correct split: putByValTransitionHandlerImpl for inline allocation (no IndexingHeader) and putByValTransitionOutOfLineHandlerImpl which calls operationReallocateButterflyAndTransition to handle IndexingHeader preservation. The non-string primitive key handlers duplicated the inline allocation path for both cases, missing the critical out-of-line variant — a classic "incomplete pattern replication" bug when a new feature mirrors an existing one.
Aaa Aaaaaaa Aa Aaaaaaaaaaaaaaaa Aaaaaa a Aaaaaaaaa Aaaaaaaaaaa Aaaa a Aaaaa Aaaaa Aaaaa Aaaa Aaaaaa Aa a Aaaaaaaaaa Aaaaaaaaa Aaa Aaaaaa Aaaaaaaaaaaaaa a Aaaa Aa a Aaa Aaaa Aa Aaaaaaa Aa Aaaaaaaaaaa Aa Aaa Aaaaa Aaaaaaaaaa Aaaaaaaa Aaa Aa Aaaaaa Aaaaaaaaaaaa Aaa Aaaaaaaaa Aaaa a Aaaaaa Aaaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aaaa Aaaa Aaaaaaaa Aaaaaaa Aa Aaaaaa Aaa Aaaaaaaaaaa
Aaaaaaa Aaa Aaaaaa Aaaaaaaaaaaaaa Aaaaaa Aaaaaa Aaaaaa Aa Aaaa Aaaaaaaaaa Aa Aaaaaa Aaa Aaaaaaaa Aaaaaaaaaa Aaaaaaa Aaaa Aaaaaa Aa Aaa Aaaaaaaaa Aa Aaaaaa Aaaaaaaaa Aaaaaaa Aaaaaaaaa Aaa Aaaaaa Aaaaaaaaa Aaaaaaaa a Aaaaaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaa Aaaaaaaaa Aa a Aaaaa Aaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaaa a Aaaaaaaa Aaaaaaaa Aaaaaaa Aaaa Aaaaa Aaaaaaa Aaaaaa Aaaa Aaaaa Aaaaaaaaa Aaaaa Aaaaa Aaaaa Aa Aaa Aaaaaaaaa Aaaaaa Aaa Aaaaaa Aaaa Aaaaaa Aaaaaa Aaaaaa Aaaaaa Aa Aaaa Aaa Aaaaaaaa Aaaaaaaaa Aa a Aaaaaaaaaaaaaaaa Aaaaaaaaaa Aaa Aa Aaa Aaaaaaa Aaaaa Aaaaaa Aaaaaaaaaaaaaa Aaaa Aaaaa Aaaaaaa Aaa Aa Aaa Aaaaaa Aaaaaaaa Aaaa Aaaaa Aaaaaaa Aa Aaa Aaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaaaaaaaa Aaaaaaa Aaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaa Aaa Aaaaaaaaaaaaaa Aaa Aaaaa Aaaaa Aaaaa Aaaaaaaa Aaaaaaaa Aaaa Aaa Aaaaaa Aaaaaaaa Aaa Aaaaaa Aaaaaaa Aa Aaaaaaaa Aaa Aaaaaaaa Aaaa Aaaaaaaaaa Aaaaa Aaaaa Aaaaaaaaaa Aaaaaaa Aaaaaaaa Aa Aaaaaaa Aaaa Aaaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaaaaa Aa Aaaaaaa Aaaaaaa Aaa Aaaaaaaa Aaaaaa Aaaaaaa Aaaa Aaaaaaaaaaaaa Aa Aaaaaaaaa Aaaa Aaa Aaa Aaaa Aaaa Aaaaaaa a Aaaaaaaaa Aaaaaaaaaaaa Aaaaa Aa Aa a Aaaaa Aaaaaa Aaa Aaaaaaa Aa a Aaaaaaaaaa Aaaaaaaaa Aaaa
Aaaaaaaaa Aaa Aaaaa Aaaaaaaa Aa Aaa Aaa Aaaaaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaa Aa Aaaaaaaa Aaaa Aaa Aaa Aaaaaaaa Aaa Aaaa Aaaaaaaaaa Aaaaaaaaa Aaa Aaaaaaa Aaaa Aaa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaaaa Aaa Aaaaaaaaaa Aaaaa
🔒Detailed analysis of how zeroed IndexingHeader metadata interacts with typed array bounds checking, and whether the corruption yields a usable memory access primitive
Subscribe to read more
Audit directions
a Aaaa Aaaaaaa Aaaaaaaa Aaaa Aaaaaaa Aaaaaa Aaaaaaaaa Aaaaaaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaa Aaa Aa Aaaaaaaaaa Aaaaaaa Aaaa Aaaaaaaaaa a Aaa Aaaaaaaaa Aa Aaaaaaaaa Aaa Aaaaaaa Aaaa Aaaaaaaaaaaaaaa Aaaaaa Aaaaaaa Aaaaaaaaa Aaaaaaaaa Aaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaa Aaaa Aaa Aaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaaa Aaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaa Aaa Aaaaaa Aaaaaaaaa Aaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaa Aaa Aaaaaaaaa
a Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaaaa Aa Aaa Aaaaaaaa Aaaa Aaa Aa Aaa Aaaa Aaaaaaa Aa Aaaaa Aaa Aa Aaaaaaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaa Aaaaaa Aaaa Aaaaaaa Aaaaaaa Aaaa Aaaaaa Aaa Aaaa Aaa Aa Aaaaa Aaaa Aaa Aaaaaaaa Aaa Aaaaa Aaaaa Aaaaaaa Aaaaa Aaaaaaaa Aaaaa Aa Aaa Aaaaa Aaaa Aaaaaaa Aaaa a Aaaaa Aaaa Aaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaa Aaaaa Aaa Aaaaaaaa Aaaaaaaaaa Aaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaaa Aaa Aaaaaa Aaaa Aaaaaaaaa Aaaaaaaa Aaaa Aa Aaa Aaaaaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaa
a Aaaaaaaaaaa Aaaaaaaaaaaa Aaaaa Aaaa Aa Aaa Aaaaaaaa Aaa Aaaaaa Aaaaaaaaa Aaaaaa Aaa Aa Aaaaaaa Aaa Aaaa Aaaa Aaaaaaaaa a Aaa Aaaaaaaaa Aaa Aaaaaa Aaaa Aaaa Aa Aaa Aaa Aaaa Aaaaaa Aaa Aaaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaaaaa Aaaaaaaaa Aa Aaaaaa Aaaa Aaaaa Aa Aaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaa Aaa Aaaaaaaaa Aaaaa Aaaaa Aaaaaaaaaaaa
🔒Multiple audit patterns identified for IC handler completeness and butterfly reallocation correctness, with concrete search targets
Subscribe to read more