Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 5b5081adba8f0891b114ba01a843fbbfdb6b7cd7
https://github.com/WebKit/WebKit/commit/5b5081adba8f0891b114ba01a843fbbfdb6b7cd7
Author: Basuke Suzuki <[email protected]>
Date: 2026-06-03 (Wed, 03 Jun 2026)
Changed paths:
M Source/WebKit/UIProcess/SuspendedPageProxy.cpp
M Source/WebKit/UIProcess/SuspendedPageProxy.h
M Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp
M Source/WebKit/UIProcess/WebBackForwardCacheEntry.h
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
Log Message:
-----------
[Site Isolation] Evicting a cross-site page from the back/forward cache
crashes the iframe process
https://bugs.webkit.org/show_bug.cgi?id=316114
rdar://178543188
Reviewed by Sihui Liu.
When a cross-site Site Isolation page is held in the back/forward cache via a
SuspendedPageProxy, evicting that cache entry never cleared the cached page in
the
iframe processes. WebBackForwardCacheEntry only sent ClearCachedPage to the main
process and to the iframe processes tracked in m_cachedChildren, which is empty
for
the cross-site SuspendedPageProxy path. The SuspendedPageProxy teardown then
sent a
plain Close to the iframe process, so it ran WebPage::close() with its document
still
in the back/forward cache and Page::~Page() asserted (m_rootFrames was not
empty).
The cached subframe processes live in one of two places depending on the path:
the
in-process cache path records them on
WebBackForwardCacheEntry::m_cachedChildren, while
the cross-site path leaves them in the frozen frame tree of the
SuspendedPageProxy.
Unify both into a single accessor: SuspendedPageProxy now records the frame
item it was
suspended under (suspendedFrameItemID) and exposes its iframe processes, and
WebBackForwardCacheEntry::iframeProcesses() folds those into the
m_cachedChildren set.
A new WebBackForwardCacheEntry::allProcesses() adds the main frame process, so
the
destructor clears every relevant process through one path.
The destructor sends ClearCachedPage to allProcesses() before m_suspendedPage is
released at the end of the destructor; ~SuspendedPageProxy then sends Close,
and IPC is
FIFO per connection, so ClearCachedPage arrives first and the iframe leaves the
back/forward cache cleanly. A SuspendedPageProxy can be shared across
same-process
entries, so its frame id may differ from ours; only the entry the page was
actually
suspended under (suspendedFrameItemID() == m_backForwardFrameItemID)
contributes the
suspended page's iframe processes, other entries do nothing.
This crash is only reachable once MultiProcessBackForwardCacheEnabled is on
under Site
Isolation, so the new test enables the preference explicitly.
* Source/WebKit/UIProcess/SuspendedPageProxy.cpp:
(WebKit::SuspendedPageProxy::startSuspension):
(WebKit::SuspendedPageProxy::iframeProcesses):
* Source/WebKit/UIProcess/SuspendedPageProxy.h:
(WebKit::SuspendedPageProxy::suspendedFrameItemID const):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp:
(WebKit::WebBackForwardCacheEntry::~WebBackForwardCacheEntry):
(WebKit::WebBackForwardCacheEntry::iframeProcesses const):
(WebKit::WebBackForwardCacheEntry::allProcesses const):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TEST(SiteIsolation, MultiProcessBFCacheCrossSiteEvictionDoesNotCrashIframe)):
Canonical link: https://commits.webkit.org/314507@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications