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

Reply via email to