Skip to content

StabilityTracer: MobileSafari at Received an invalid message 'WebLockRegistryProxy_ClientIsGoingAway'#66888

Draft
RupinMittal wants to merge 1 commit into
WebKit:mainfrom
RupinMittal:eng/InvalidMessageWebLockRegistryProxy_ClientIsGoingAway
Draft

StabilityTracer: MobileSafari at Received an invalid message 'WebLockRegistryProxy_ClientIsGoingAway'#66888
RupinMittal wants to merge 1 commit into
WebKit:mainfrom
RupinMittal:eng/InvalidMessageWebLockRegistryProxy_ClientIsGoingAway

Conversation

@RupinMittal

@RupinMittal RupinMittal commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

35d9135

StabilityTracer: MobileSafari at Received an invalid message 'WebLockRegistryProxy_ClientIsGoingAway'
https://bugs.webkit.org/show_bug.cgi?id=315738
rdar://178065152

Reviewed by NOBODY (OOPS!).

The message check added to requestLock() and clientIsGoingAway():
MESSAGE_CHECK(m_process->hasCommittedClientOrigin(clientOrigin));
may still fail after the fix in rdar://177020691.

The issue is that the ClientOrigins that the UI process stores in the map
may be different than the ones sent by web process to requestLock().

The ClientOrigins that the web process sends are computed in
WebLockManager::clientOriginFromContext(). In cases where the document's
topOrigin or securityOrigin is inherited from the parent or owner document,
this function will indeed use the inherited origins.

But the UI process side doesn't account for inherited security origins.
WebFrameProxy::didCommitLoad() computes the topOrigin and securityOrigin
straight from the URL. So in the case of an about:blank URL, it will
compute an opaque securityOrigin, whereas the web process will find and
send over the inherited securityOrigin.

The new test WebLocks.CrossSiteIframeUsingLocksInsideAboutBlankPopup
demonstrates such a scenario. In this case, there is a main frame hosted
on server1. It creates an about:blank popup and embeds in it an iframe that
is hosted on server2.

The UI process will store the following (topOrigin, securityOrigin):
main frame: { server1, server1 }
popup:      { opaque1, opaque2 }
iframe:     { opaque3, server2 }

The web process accounts for inherited origins and will have:
main frame: { server1, server1 }
popup:      { server1, server1 }
iframe:     { server1, server2 }

So when the iframe sends the requestLock() or clientIsGoingAway() IPCs,
its ClientOrigin isn't found in the map, and the message check kills the
web process.

We need to replicate the inheritance logic of the web process in the UI process.
This already exists in WebFrameProxy::updateDocumentSecurityOrigin(). So we fix
the issue by ensuring that we pass the creator (parent or opener if there's no
parent) to this function so that it correctly computes and sets the
documentSecurityOrigin and then using these computed securityOrigins.

* Source/WebKit/UIProcess/WebFrameProxy.cpp:
(WebKit::WebFrameProxy::didCommitLoad):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebLocks.mm:
(TestWebKitAPI::TEST(WebLocks, CrossSiteIframeUsingLocksInsideAboutBlankPopup)):

35d9135

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows Apple Internal
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ⏳ 🛠 win ⏳ 🛠 ios-apple
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug loading 🧪 wpe-wk2 ⏳ 🧪 win-tests ⏳ 🛠 mac-apple
✅ 🧪 webkitperl loading 🧪 ios-wk2 ⏳ 🧪 api-mac ⏳ 🧪 api-wpe ⏳ 🛠 vision-apple
⏳ 🧪 ios-wk2-wpt ⏳ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
⏳ 🛠 🧪 jsc-x86-64 ⏳ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
⏳ 🛠 🧪 jsc-debug-arm64 ⏳ 🛠 ios-safer-cpp ✅ 🧪 mac-wk2 ⏳ 🧪 gtk-wk2
✅ 🛠 vision ⏳ 🧪 mac-AS-debug-wk2 ⏳ 🧪 api-gtk
✅ 🛠 vision-sim ✅ 🛠 playstation
✅ 🧪 vision-wk2 ⏳ 🧪 mac-intel-wk2
✅ 🛠 tv ⏳ 🛠 mac-safer-cpp
✅ 🛠 tv-sim ✅ 🧪 mac-site-isolation
✅ 🛠 watch
✅ 🛠 watch-sim

…RegistryProxy_ClientIsGoingAway'

https://bugs.webkit.org/show_bug.cgi?id=315738
rdar://178065152

Reviewed by NOBODY (OOPS!).

The message check added to requestLock() and clientIsGoingAway():
MESSAGE_CHECK(m_process->hasCommittedClientOrigin(clientOrigin));
may still fail after the fix in rdar://177020691.

The issue is that the ClientOrigins that the UI process stores in the map
may be different than the ones sent by web process to requestLock().

The ClientOrigins that the web process sends are computed in
WebLockManager::clientOriginFromContext(). In cases where the document's
topOrigin or securityOrigin is inherited from the parent or owner document,
this function will indeed use the inherited origins.

But the UI process side doesn't account for inherited security origins.
WebFrameProxy::didCommitLoad() computes the topOrigin and securityOrigin
straight from the URL. So in the case of an about:blank URL, it will
compute an opaque securityOrigin, whereas the web process will find and
send over the inherited securityOrigin.

The new test WebLocks.CrossSiteIframeUsingLocksInsideAboutBlankPopup
demonstrates such a scenario. In this case, there is a main frame hosted
on server1. It creates an about:blank popup and embeds in it an iframe that
is hosted on server2.

The UI process will store the following (topOrigin, securityOrigin):
main frame: { server1, server1 }
popup:      { opaque1, opaque2 }
iframe:     { opaque3, server2 }

The web process accounts for inherited origins and will have:
main frame: { server1, server1 }
popup:      { server1, server1 }
iframe:     { server1, server2 }

So when the iframe sends the requestLock() or clientIsGoingAway() IPCs,
its ClientOrigin isn't found in the map, and the message check kills the
web process.

We need to replicate the inheritance logic of the web process in the UI process.
This already exists in WebFrameProxy::updateDocumentSecurityOrigin(). So we fix
the issue by ensuring that we pass the creator (parent or opener if there's no
parent) to this function so that it correctly computes and sets the
documentSecurityOrigin and then using these computed securityOrigins.

* Source/WebKit/UIProcess/WebFrameProxy.cpp:
(WebKit::WebFrameProxy::didCommitLoad):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebLocks.mm:
(TestWebKitAPI::TEST(WebLocks, CrossSiteIframeUsingLocksInsideAboutBlankPopup)):
@RupinMittal RupinMittal self-assigned this Jun 10, 2026
@RupinMittal RupinMittal added the New Bugs Unclassified bugs are placed in this component until the correct component can be determined. label Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Bugs Unclassified bugs are placed in this component until the correct component can be determined.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants