← WebKit — 2026-W40
152ae41b47b18143f47ebf5bb945c5d8a656e5b6 [JSC] Assert that no request outlives the collector thread instead of checking for it in relinquishConn()
severity low
class Race
confidence 0.3
signal score 7.17
Source/JavaScriptCore/heap
Primitive: GC collector-thread shutdown race (conn handoff after m_threadShouldStop)
Triage note: Adds RELEASE_ASSERT(!m_threadShouldStop) in Collector::requestCollection and Heap::finishRelinquishingConn and removes the early threadShouldStop bail in relinquishConn. This is predominantly assertion instrumentation chasing a GC collector-thread-stop/conn-handoff invariant; the small logic change is not a clearly-fixed, attacker-reachable memory-safety bug, so instrumentation-grade only.
Triage note: Adds RELEASE_ASSERT(!m_threadShouldStop) in Collector::requestCollection and Heap::finishRelinquishingConn and removes the early threadShouldStop bail in relinquishConn. This is predominantly assertion instrumentation chasing a GC collector-thread-stop/conn-handoff invariant; the small logic change is not a clearly-fixed, attacker-reachable memory-safety bug, so instrumentation-grade only.
Structural signals: security_assert (+4.87), msg_soft (+1.0), surgical (+1.3)
Commit message
[JSC] Assert that no request outlives the collector thread instead of checking for it in relinquishConn()
https://bugs.webkit.org/show_bug.cgi?id=325741
rdar://188764819
Reviewed by Yusuke Suzuki.
Heap::relinquishConn() kept the conn once the collector thread was stopping, so that it would not hand the
conn to a thread that had stopped. The check never fires: relinquishConn() is only called from
Heap::waitForCollector(), and nothing waits after Collector::stopThread(). Heap::shutDown()'s own wait
comes first, and Heap::collectSync() and Heap::preventCollection() return before waiting once shutDown()
has cleared m_isSafeToCollect. Handing over the conn would not strand anything anyway, since no request can
outlive the thread: stopThread() asserts the queue is empty, and with m_isSafeToCollect cleared nothing can
queue another.
Remove the check, which was also the one read of m_threadShouldStop without the thread lock, and instead
assert what it protected against, under the lock: that nothing is queued for the thread once it is
stopping.
* Collector::requestCollection() asserts the thread is not stopping.
* Heap::finishRelinquishingConn() asserts it before waking the thread for a queued request.
No change in behavior.
* Source/JavaScriptCore/heap/Collector.cpp:
(JSC::Collector::requestCollection):
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::relinquishConn):
(JSC::Heap::finishRelinquishingConn):
Canonical link: https://commits.webkit.org/322275@main
Before / after
Loading diff…
On This Page