← WebKit — 2026-W39

04f7d4b2e3f82a490090108c470643d940f20ae7  [JSC] getInternalProperties() can dereference a freed FinalizationRegistry unregister token

severity medium class UAF confidence 0.82 signal score 6.3 Source/JavaScriptCore/inspector patch-now
Primitive: FinalizationRegistry live/dead registration JSValues (target/heldValue/unregisterToken) unrooted during array construction -> GC collects them
Triage note: Adds, under #ifndef RC_REMOVE_SEC_ACCEL_3, a MarkedArgumentBuffer protecting every liveRegistration/deadRegistration target, heldValue and unregisterToken before constructEmptyArray/array population in JSInjectedScriptHost::getInternalProperties; without rooting, allocation-triggered GC can collect those cells causing use-after-free. The RC_REMOVE_SEC_ACCEL_3 bracket marks this as a silent security fix.
Structural signals: msg_strong (+3.0), msg_medium (+2.0), surgical (+1.3)

Commit message

[JSC] getInternalProperties() can dereference a freed FinalizationRegistry unregister token
https://bugs.webkit.org/show_bug.cgi?id=325300
rdar://186901796

Reviewed by Mark Lam.

JSInjectedScriptHost::getInternalProperties() snapshots the registry's live and
dead registrations under cellLock() into FastMalloc-backed Vectors of raw
JSCell's. Those cells (the targets and unregister tokens) are only weakly
referenced by the registry and the Vectors aren't visited, so a collection
provoked by the allocations that build the result arrays can free one
mid-walk, after which the loop calls putDirect and the marker later visits a
dangling cell. Root the snapshot in a MarkedArgumentBuffer for the duration of
the walk. Covers both the live and dead loops, since the live target is weakly
held too.

Test: sar3/inspector/model/remote-object/finalizationregistry-unregister-token-use-after-free.html

* LayoutTests/sar3/inspector/model/remote-object/finalizationregistry-unregister-token-use-after-free-expected.txt: Added.
* LayoutTests/sar3/inspector/model/remote-object/finalizationregistry-unregister-token-use-after-free.html: Added.
* Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::getInternalProperties):

Identifier: 316606.799@safari-7625-branch

Before / after

Loading diff…