[10] Use WeakHashSet::forEach to iterate over set where the iterator might be invalidated
Severity: Medium | Component: WebCore PageGroup | 42beed9
Rated Medium because the observable effect is iterator invalidation reachable from script-driven re-entrancy in caption-preference fan-out, the analyst's confidence is 0.85, and escalation beyond a renderer crash depends on freed-slot reclamation timing — useful as one stepping-stone primitive in a chain.
Source/WebCore/page/PageGroup.cpp
void PageGroup::captionPreferencesChanged()
{
- for (Ref page : m_pages)
- page->captionPreferencesChanged();
+ m_pages.forEach([](auto& page) {
+ page.captionPreferencesChanged();
+ });
BackForwardCache::singleton().markPagesForCaptionPreferencesChanged();
}
Patch Details
PageGroup::captionPreferencesChanged() switches from a range-based for (Ref page : m_pages) over its WeakHashSet<Page> member to m_pages.forEach([](auto& page) { ... }). The lambda calls page.captionPreferencesChanged() on each Page. A SaferCPPExpectations file is also updated, likely removing this site from a known-bad-pattern allowlist.
Iterator invalidation in a weak collection traversal that re-enters script-observable code capable of mutating the same collection.
Background
WeakHashSet<T> holds weak references to T; entries whose referent is destroyed become empty and are eventually cleaned up. Iterating with a range-based for materialises a Ref per live entry but the iterator walks the underlying hash table. WeakHashSet::forEach is a member helper that strongifies live entries up front so add/remove/cleanup of weak slots during the callback does not corrupt the in-flight walk. PageGroup::captionPreferencesChanged notifies each Page that user caption preferences changed; that notification can reach HTMLMediaElement/TextTrackList listeners and trigger synchronous JS-observable work.
Analysis
The per-element callback can synchronously re-enter script — caption/track lifecycle, media element notifications, possibly synchronous event dispatch — and that re-entry can mutate m_pages: a Page can be destroyed (collapsing its weak entry), or callback-driven allocation can cause the WeakHashSet to amortize-remove dead entries during a rehash. Either invalidates the range-based-for iterator.
Aaa Aaaaaa Aaaaa Aaa Aaaaaaaa Aaaaaaaaaa Aaaa Aaaa Aaa Aaaaaaa a Aaaaaaaaaaaaaa Aa a Aaaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaa a Aaaaaaa Aaaa Aa Aaaa Aaaaa Aa Aaaaaaaa Aaa Aaa Aaaaa Aaaaaaaaaaaaaaaaaaa Aa Aaa Aaa Aaaaa Aaaaaaaa Aaaaaaaaaaa Aa a Aaaaaa Aaaaa Aaaaaa Aaaaaaaaa Aaa Aaa Aaa Aa Aaaaa Aaaaaaaa Aaaa Aaaaaaaaaaaa Aaaaaaaaa Aa Aaa Aaa Aaaaa Aaaa Aa Aaaaaaaaaa
Aaaa Aaaaaaaaaaaaa Aaaaaaa Aaaaaa Aaaaaa Aaaaaa Aaa Aaaaaaaaaa Aaaaaaaa Aaa Aaaaaaa a Aaaaaaaaaaaaaaa Aaaa a Aaaa Aaaaaaaaaa Aaaa a Aaaaaaaaaaa Aaaaaaaa Aaaa Aaa Aaaaaaaa Aaaaaa a Aa Aaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaa Aa Aaaaaaaa Aaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaa Aaaaaa Aaaaa Aaaa Aaaaaaaaaaaaa Aaaaaa
🔒The re-entrancy and lifetime implications of weak-collection iteration during script-observable callbacks are explored, along with the practical reach of the resulting primitive.
Subscribe to read more
Audit directions
a Aaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaa Aaa Aaaa Aaaaaaaaaaa Aaaa Aaaaaaaaa Aaaa Aaa Aaaaaaaa Aaaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaaa Aaaa Aaaa Aaaa a Aaa Aaaa Aaaaaa a Aaaaaaaa Aaaaa Aaa Aaaaaaaaaa Aaaa Aaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aaaa Aaaa Aaaa Aa Aaaaaaaaaaaaa Aa Aaaaaaaa Aa Aaaaaaaaaa
a Aaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa Aaaaaa Aaaaaaaaa Aaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa a Aaaaaaaaa Aaaaaa Aaaa Aaaaa Aaa Aaa Aaaa Aaaaaaaaaa
a Aaaaaaaaaa Aaaaaaa Aa Aaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaa Aaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaa Aaa Aaaaaaaa Aaaaaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaa Aaaaaaaaa Aa Aaaaaaaaaaa Aaaaa Aaaaaaaaa
a Aaaaaa Aaaaaaaaaaaaaaaaaaaaaa Aaaaaa Aa Aaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaaaaa Aaa Aaaa Aaaaaaaaa Aaaaaaaaa
🔒Multiple reusable audit patterns identified for iterator-invalidation bugs across WebCore, including a concrete worklist source for variant discovery.
Subscribe to read more