[11] [JSC] Use span's length in genericTypedArrayViewProtoFuncSortImpl
Severity: High | Component: JSC TypedArray prototype | c852586
Rated High because the diff fixes a TOCTOU on a GSAB-backed TypedArray's length: a parallel grow desynchronizes length() from typedSpan().size(), and the sort body uses both — an OOB during element copy.
genericTypedArrayViewProtoFuncSortImpl performed two independent length reads — thisObject->length() and thisObject->typedSpan(). With a Growable SharedArrayBuffer backing, another agent's grow() between the reads could make them disagree.
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
- size_t length = thisObject->length();
+ auto originalSpan = thisObject->typedSpan();
+ size_t length = originalSpan.size();
+
if (length < 2)
return JSValue::encode(thisObject);
- auto originalSpan = thisObject->typedSpan();
-
Vector<typename ViewClass::ElementType, 256> vector;
Patch Details
The order is swapped: originalSpan is constructed first and length is derived from originalSpan.size(). Single snapshot, single source of truth.
TOCTOU on a shared-memory length: deriving two values from two independent reads of the same race-prone quantity instead of a single snapshot.
Background
A Growable SharedArrayBuffer (constructed with maxByteLength) can be grown via SharedArrayBuffer.prototype.grow. A length-tracking TypedArray view over a GSAB returns a length derived from the current SAB byte length; SABs are shared across agents (main thread and Workers), so each length re-derivation reads a value that can change underneath the implementation. std::span here is a {pointer, size} pair captured at call time. %TypedArray%.prototype.sort accepts a user comparator and is implemented in C++ by copying into a work buffer, sorting, then copying back.
Analysis
length reflected the pre-grow size while originalSpan reflected post-grow. The sort body uses both: the work vector is sized from length, while the span is the source/destination of element copies and sort callbacks. The invariant length == originalSpan.size() no longer held.
Aaaaaaa Aaaaaa Aaaaaa a Aaaa Aaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaa Aaaa Aaaaaaaa Aaa a Aaaaaaaaaaaaaaa Aaaaaaaaaaaa Aaaa Aaa Aaaa Aaa Aaa Aa a Aaaaaa Aaaa Aaaaa Aa Aaaaaaaaaaaaa Aa Aaa Aaaa Aaaaaaa Aaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaa Aaaa Aaaaaaaa Aaaa Aaaaaaaaaa Aaaaaa a Aa Aaa Aaaa Aa Aaaaa Aaaaaa Aaaaaaa Aaaa Aa Aaaaaaaaaaa Aaaaaaa Aa Aaa Aaaa Aaaaa Aaaaaaa Aaaa Aaa Aaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaa Aaaaaaaa Aaaaaa Aaa Aaa Aaaaaaa Aaaaaaa Aa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaaa Aa Aaaaaaaa Aaaaaaaaaaa Aaaa Aaa Aaaa Aaaaaa Aaa a Aaaaaa Aaaaa Aaaaaa a Aaaaaaa Aaa Aaaaaaaaa Aaaaaaaa Aa Aaa Aaaa Aaaa Aaaaaa Aa Aaa Aaaaaaaaaaa Aaaaaaaa
🔒The concurrency and memory-consistency implications of this race are analyzed in depth, alongside the exploitation feasibility from web content.
Subscribe to read more
Audit directions
a Aaaaa Aaaaaaaaaaa Aaaaaa Aaaaa Aa a Aaaaaaaaaaaaaaa Aaaaaaaaaa Aaaa a Aaaaaaa Aaaaa Aaaaa Aaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaa a Aaaaaaaaaaaaa Aaaaaaaaaaa Aa Aaa Aaaaaaaaaaa Aa Aaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaaa Aaaa Aaaaa Aaaaaaa Aaa Aaa Aa Aaa Aaaaaaaaaa Aaaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaaaaa Aaaaaaa
a Aaaaaaaaaaaa Aaaaaa a Aa Aaaaaaaa Aaaaaaaa Aaaa Aaaaaaa Aa Aaaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaaaa Aa a Aaaaaaaaaaa Aaaaaa Aaaaa Aaa Aaaaaaaaaa Aaaaaa Aaaa Aaaaa a Aaaaaaaaaaa Aaaaaaaa Aaa Aaaaaa Aaa Aaaaaaaaaaaaa Aaaa Aaaaaaaa Aaa Aaaaaaaa Aaaaaaaaa
a Aaaaaaaaaa Aaaaaaa Aaa Aaa Aaa Aaaaaaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaa Aaa Aaaaaa Aaaa Aaaaaa Aaaaaaaaaa Aaaaaaaaa a Aaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaa Aaaaa Aaaaaaa Aaaa Aaaaaaa Aa Aaaaaaaaa
a Aaaaaaaaa Aaa Aaaaaaaaaa Aaaa Aaaa Aaaaaaaa Aa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaa Aa Aaaaa Aaa Aaaa Aaaaaaa Aaaa Aaaaaaaaaaaaaa
🔒Multiple reusable audit patterns identified across JSC's TypedArray prototype implementations, with concrete starting points for variant discovery.
Subscribe to read more