Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: bafdda395eebfb3bf97f2759eadcae9c85347b15
      
https://github.com/WebKit/WebKit/commit/bafdda395eebfb3bf97f2759eadcae9c85347b15
  Author: BJ Burg <[email protected]>
  Date:   2026-05-29 (Fri, 29 May 2026)

  Changed paths:
    M LayoutTests/platform/mac-wk2/TestExpectations
    M Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp
    M Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h
    M Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp

  Log Message:
  -----------
  [Site Isolation] Web Inspector: disable instrumentation for the old process 
on didCommitProvisionalPage
https://bugs.webkit.org/show_bug.cgi?id=315312
rdar://177178776

Reviewed by Sihui Liu.

REGRESSION(313207@main): [macOS Debug] ASSERTION FAILED:
!m_messageReceiverMapCount in http/tests/ssl/applepay/ApplePayButton.html.

Two complementary fixes:

(1) Pair add/remove on full-page cross-origin navigation.

313741@main fixed one half of ProxyingNetworkAgent's receiver leak --
the disable() walk now reaches stale processes via the registration map.
CI reports the assertion still flakes, and inspecting the
process-swap hooks shows why: didCommitProvisionalFrame disables
instrumentation on the old process when an iframe swaps, but
didCommitProvisionalPage (the full-page cross-origin navigation hook)
does not. So a top-level cross-origin nav under inspection leaves
m_instrumentedProcessPageCounts referencing the swapped-out process and
its IPC receiver registration intact. When that process eventually goes
away or the inspector tears down, MessageReceiver's destructor asserts.

Mirror the didCommitProvisionalFrame pattern in didCommitProvisionalPage:
look up the old WebProcessProxy by ProcessIdentifier, call
disableInstrumentationForProcess for (oldProcess, oldWebPageID) so the
addMessageReceiver registration is paired by a removeMessageReceiver,
and enableInstrumentationForProcess for the new (process, pageID).

(2) Pin the instrumented WebProcessProxy alive while we hold a receiver
registration on it. This design is already proven to work by ProxyingPageAgent.

The disable() walk and the ~ProxyingNetworkAgent backstop both used
WebProcessProxy::processForIdentifier() to find the proxy to call
removeMessageReceiver on. That lookup returns null once the
WebProcessProxy has been destructed -- but the IPC receiver map entry
isn't torn down until later, so the receiver's m_messageReceiverMapCount
stays nonzero and ~MessageReceiver fires the ASSERT. This was first
caught locally on http/tests/storageAccess/deny-due-to-no-interaction-...
ephemeral.https.html via the new ProxyingPageAgent added in #61177, but
ProxyingNetworkAgent has the identical pattern and same latent UAF.

Add a parallel HashMap<ProcessIdentifier, Ref<WebProcessProxy>> on both
agents. enableInstrumentationForProcess populates it; cleanup paths drop
the pin once the last (process, pageID) registration for that process
goes away. With the pin, disable() and ~ProxyingNetworkAgent /
~ProxyingPageAgent can use the pinned ref directly and never hit a null
processForIdentifier() lookup.

* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp:
(Inspector::ProxyingNetworkAgent::removeAllRegisteredReceivers):
(Inspector::ProxyingNetworkAgent::enableInstrumentationForProcess):
(Inspector::ProxyingNetworkAgent::disableInstrumentationForProcess):
(Inspector::ProxyingNetworkAgent::disable):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h:
* Source/WebKit/UIProcess/Inspector/WebPageInspectorController.cpp:
(WebKit::WebPageInspectorController::didCommitProvisionalPage):

Canonical link: https://commits.webkit.org/314195@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to