← All issues

[3] WKRevealItemPresenter: re-entrancy UAF in showContextMenu

Severity: Medium | Component: WebKit UIProcess (macOS) | d089fe1

Rated Medium because the diff fixes a use-after-free in the UI process triggered by an IPC handler re-entering during a nested AppKit modal run loop and reassigning the sole-owner WebViewImpl::m_revealItemPresenter member. The UAF is reachable from WebContent via crafted data-detection click results; sandbox escape from this UAF requires a separate exploitation chain the diff does not establish.

A crash occurs in -[WKRevealItemPresenter showContextMenu] because the presenter is held by a single strong reference m_revealItemPresenter in WebViewImpl. During the modal popup, this reference may be cleared by a new data-detection click arriving via IPC, which overwrites m_revealItemPresenter with a newly allocated presenter, releasing the old one. The fix uses protect(m_revealItemPresenter) to retain the presenter for the duration of the showContextMenu call.

Source/WebKit/UIProcess/mac/WebViewImpl.mm

m_revealItemPresenter = adoptNS([[WKRevealItemPresenter alloc] initWithWebViewImpl:*this item:adoptNS([PAL::allocRVItemInstance() initWithDDResult:info.result.get()]).get() frame:info.elementBounds menuLocation:clickLocation]);
[m_revealItemPresenter setShouldUseDefaultHighlight:NO];
- [m_revealItemPresenter showContextMenu];
+ [protect(m_revealItemPresenter) showContextMenu];

A single-line change in WebKit::WebViewImpl::handleClickForDataDetectionResult. The direct call [m_revealItemPresenter showContextMenu] is replaced with [protect(m_revealItemPresenter) showContextMenu]. protect() is a WebKit idiom that materializes a local strong reference (a RetainPtr<> temporary) from a smart-pointer member; the temporary's lifetime extends through the full statement, so the presenter object is held alive for the entire duration of the modal showContextMenu invocation regardless of any subsequent reassignment to m_revealItemPresenter.

Sole-owner member pointer mutated by re-entrant IPC during a nested modal run loop, freeing the receiver of the in-flight method call.

WKRevealItemPresenter is an Objective-C UI helper that displays a context menu for a data-detection match (phone number, address, calendar event) using Apple's Reveal framework. WebViewImpl is the per-WKWebView C++ object on macOS that owns UI-process state, including a single strong reference m_revealItemPresenter held via an adoptNS-style smart pointer. handleClickForDataDetectionResult is invoked when the WebContent process sends back a data-detection click hit result via IPC.

showContextMenu displays an AppKit context menu, which is modal: AppKit spins a nested run loop until the user dismisses the menu. While that nested run loop is active, the UI-process main thread continues to dispatch incoming IPC messages — meaning new messages from the WebContent process can re-enter UI-process IPC handlers before the outer showContextMenu call has returned. protect(...) is a WebKit idiom that materializes a local strong reference from a smart-pointer member so the referenced object survives even if the member is mutated during the call.

The bug is a textbook use-after-free via re-entrant overwrite of a sole-owner strong reference during a nested modal run loop. Before the fix, WebViewImpl held the WKRevealItemPresenter solely via the strong member m_revealItemPresenter. The call sequence is the dangerous shape: m_revealItemPresenter = adoptNS([[WKRevealItemPresenter alloc] init...]) allocates the presenter and stores it via assignment; the next line invokes a modal Objective-C method on that member directly.

🔒

The ownership and lifetime implications of a re-entrant IPC during a nested modal run loop are explored in depth, along with what an attacker could realistically gain in the UI process.

더 확인하려면 구독해 주세요

🔒

Multiple reusable audit patterns identified across UIProcess presenter/controller members, with concrete starting points for variant discovery on macOS.

더 확인하려면 구독해 주세요