[AppKit Gestures] Reentrancy UAF in PositionInformationManager pending-handler loop
Source/WebKit/UIProcess/mac/PositionInformationManager.cpp
PositionInformationManager runs in the UIProcess and queues callbacks (m_pendingHandlers) that await position-information updates from AppKit gesture handling. Its design explicitly supports reentrancy: a callback invoked during invokeAndRemovePendingHandlers can call back into doAfterUpdate() and enqueue new handlers via constructAndAppend(), which may grow and reallocate the Vector's backing store. A range-based for loop captures begin()/end() once at loop start, so once a reentrant callback reallocates the buffer mid-iteration, those cached pointers reference freed memory and any further dereference of slot is a use-after-free.
The fix replaces the range-based loop with an index-based one that re-reads size() and re-indexes m_pendingHandlers[index] each iteration, correctly picking up the reallocated buffer.
Range-based (buggy): Index-based (fixed):
for (auto& slot : m_pendingHandlers) for (index = 0; index < size(); ++index)
caches begin/end once slot = m_pendingHandlers[index]
callback() reenters callback() reenters
constructAndAppend() reallocates may reallocate
cached ptrs -> freed memory next iter re-indexes live buffer
slot-> ... UAF (safe)
Significance
A reentrancy-driven UAF in a UIProcess callback queue reachable from AppKit gesture handling, where the buggy pattern is a reusable template likely present in other WebKit callback queues.
Audit directions
The fixed shape — reentrant synchronous callbacks mutating a Vector that is being iterated — recurs across WebKit's UIProcess pending-request/callback queues. Narrow: grep PositionInformationManager and sibling *Manager classes for range-based for loops over m_pending* vectors whose body invokes a callback capable of reentering and calling append/constructAndAppend/insert, especially in UIProcess classes handling gesture, touch, or position-info IPC replies. Wider: any range-based iteration over a Vector/HashMap whose loop body dispatches into client or JS-reachable code that can mutate the same container — the container need not be a callback queue. Widest: the general iterator-invalidation-under-reentrancy class in any container-plus-callback design. The review tell is a range-based for over a member container adjacent to a comment or method name that admits reentrancy (doAfterUpdate, "may reenter") — the presence of both in one function is the signal to switch to index-based iteration or snapshot the container first.