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