Title: [291589] trunk
Revision
291589
Author
cdu...@apple.com
Date
2022-03-21 16:46:48 -0700 (Mon, 21 Mar 2022)

Log Message

LayoutTests/imported/w3c:
BroadcastChannel instances in distinct opaque origins can communicate
https://bugs.webkit.org/show_bug.cgi?id=238090
<rdar://problem/90511155>

Reviewed by Alex Christensen.

Import web-platform-tests test coverage.

* web-platform-tests/webmessaging/broadcastchannel/opaque-origin-expected.txt: Added.
* web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html: Added.
* web-platform-tests/webmessaging/broadcastchannel/w3c-import.log:

Source/WebCore:
BroadcastChannel instances in distinct opaque origins can communicate
https://bugs.webkit.org/show_bug.cgi?id=238090
<rdar://problem/90511155>

Reviewed by Alex Christensen.

The issue is that we would use a ClientOrigin to distinguish origins for BroadcastChannel,
which relies on SecurityOriginData internally. A unique/opaque SecurityOrigin becomes an empty
SecurityOriginData upon conversion. As a result, when comparing ClientOrigin objects from
unique SecurityOrigins, they would compare as equal.

To address the issue, I introduced a new PartitionedSecurityOrigin type which is similar
to ClientOrigin but stores SecurityOrigin objects internally, instead of SecurityOriginData
objects. PartitionedSecurityOrigin's operator==() is such that different SecurityOrigins
would not be equal but the same unique SecurityOrigin would be. I then used this new
PartitionedSecurityOrigin type as key in our HashMap on the WebProcess side instead of
ClientOrigin. This allows communication between several BroadcastChannels from the same
unique origin, while preventing communication between distinct opaque origins.

When the PartitionedSecurityOrigin contains an opaque security origin, we don't involve
the Network Process at all since the destination can only be in the same WebProcess.

Test: imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html

* Headers.cmake:
* WebCore.xcodeproj/project.pbxproj:
* dom/BroadcastChannel.cpp:
(WebCore::shouldPartitionOrigin):
(WebCore::BroadcastChannel::MainThreadBridge::registerChannel):
(WebCore::BroadcastChannel::MainThreadBridge::unregisterChannel):
(WebCore::BroadcastChannel::MainThreadBridge::postMessage):
* dom/BroadcastChannelRegistry.h:
* loader/EmptyClients.cpp:
* page/PartitionedSecurityOrigin.h: Added.
(WebCore::PartitionedSecurityOrigin::PartitionedSecurityOrigin):
(WebCore::PartitionedSecurityOrigin::isHashTableDeletedValue const):
(WebCore::PartitionedSecurityOrigin::isHashTableEmptyValue const):
(WebCore::operator==):
(WTF::add):
(WTF::PartitionedSecurityOriginHash::hash):
(WTF::PartitionedSecurityOriginHash::equal):
(WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::emptyValue):
(WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::constructEmptyValue):
(WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::isEmptyValue):
(WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::peek):
(WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::take):

Source/WebKit:
BroadcastChannel instances in distinct opaque origins can communicate
https://bugs.webkit.org/show_bug.cgi?id=238090
<rdar://problem/90511155>

Reviewed by Alex Christensen.

The issue is that we would use a ClientOrigin to distinguish origins for BroadcastChannel,
which relies on SecurityOriginData internally. A unique/opaque SecurityOrigin becomes an empty
SecurityOriginData upon conversion. As a result, when comparing ClientOrigin objects from
unique SecurityOrigins, they would compare as equal.

To address the issue, I introduced a new PartitionedSecurityOrigin type which is similar
to ClientOrigin but stores SecurityOrigin objects internally, instead of SecurityOriginData
objects. PartitionedSecurityOrigin's operator==() is such that different SecurityOrigins
would not be equal but the same unique SecurityOrigin would be. I then used this new
PartitionedSecurityOrigin type as key in our HashMap on the WebProcess side instead of
ClientOrigin. This allows communication between several BroadcastChannels from the same
unique origin, while preventing communication between distinct opaque origins.

When the PartitionedSecurityOrigin contains an opaque security origin, we don't involve
the Network Process at all since the destination can only be in the same WebProcess.

* WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp:
(WebKit::toClientOrigin):
(WebKit::WebBroadcastChannelRegistry::registerChannel):
(WebKit::WebBroadcastChannelRegistry::unregisterChannel):
(WebKit::WebBroadcastChannelRegistry::postMessage):
(WebKit::WebBroadcastChannelRegistry::postMessageLocally):
(WebKit::WebBroadcastChannelRegistry::postMessageToRemote):
(WebKit::WebBroadcastChannelRegistry::networkProcessCrashed):
* WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h:

Source/WebKitLegacy:
Dust off Mac CMake build
https://bugs.webkit.org/show_bug.cgi?id=238121

Reviewed by Yusuke Suzuki.

* PlatformMac.cmake:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (291588 => 291589)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1,3 +1,17 @@
+2022-03-21  Chris Dumez  <cdu...@apple.com>
+
+        BroadcastChannel instances in distinct opaque origins can communicate
+        https://bugs.webkit.org/show_bug.cgi?id=238090
+        <rdar://problem/90511155>
+
+        Reviewed by Alex Christensen.
+
+        Import web-platform-tests test coverage.
+
+        * web-platform-tests/webmessaging/broadcastchannel/opaque-origin-expected.txt: Added.
+        * web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html: Added.
+        * web-platform-tests/webmessaging/broadcastchannel/w3c-import.log:
+
 2022-03-21  Ziran Sun  <z...@igalia.com>
 
         [selection] HTMLTextFormControlElement::subtreeHasChanged() shouldn't be called in setRangeText

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin-expected.txt (0 => 291589)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin-expected.txt	2022-03-21 23:46:48 UTC (rev 291589)
@@ -0,0 +1,4 @@
+
+PASS Opaque origin should be serialized to "null"
+PASS BroadcastChannel messages from opaque origins should be self-contained
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html (0 => 291589)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html	2022-03-21 23:46:48 UTC (rev 291589)
@@ -0,0 +1,85 @@
+<!doctype html>
+<html>
+<head>
+<meta charset=utf-8>
+<title></title>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+<!--
+promise_test(t => {
+  return new Promise((resolve) => {
+    let ifr = document.createElement("iframe");
+    ifr.src =
+      "data:text/html,<script> let bc = new BroadcastChannel(\"test\");" +
+      "bc._onmessage_ = (e) => {" +
+      "  if (e.data == \"ping\") bc.postMessage('pong');"+
+      "  else parent.postMessage({workerMessageOrigin: e.data, messageOrigin: e.origin}, \"*\"); };" +
+      "new Worker(URL.createObjectURL(new Blob([\"" +
+      "let bc2 = new BroadcastChannel('test'); bc2.postMessage('ping'); " +
+      "bc2._onmessage_ = e => bc2.postMessage(e.origin);" +
+      "\"], {type: 'text/_javascript_'}))); </script>";
+    window.addEventListener("message", t.step_func(e => {
+        assert_equals(e.data.workerMessageOrigin, "null");
+        assert_equals(e.data.messageOrigin, "null");
+        resolve();
+      }), {once: true});
+    t.add_cleanup(() => { document.body.removeChild(ifr) });
+    document.body.appendChild(ifr);
+    });
+}, "Opaque origin should be serialized to \"null\"");
+
+
+const iframe_src = (channel_name, iframe_name) => `data:text/html,<script>
+let bc2 = new BroadcastChannel("${channel_name}");
+bc2._onmessage_ = (e) => {
+  if (e.data == "from-${iframe_name}") {
+    parent.postMessage("${iframe_name}-done", "*");
+  } else {
+    parent.postMessage("fail", "*");
+  }
+};
+let bc3 = new BroadcastChannel("${channel_name}");
+bc3.postMessage("from-${iframe_name}");
+</script>`;
+
+promise_test(t => {
+  return new Promise((resolve, reject) => {
+    const channel_name = "opaque-origin-test-2";
+    const bc1 = new BroadcastChannel(channel_name);
+    bc1._onmessage_ = t.unreached_func("Received message from an opaque origin");
+
+    // We'll create an iframe and have it send a BroadcastChannel message
+    // between two instances. Once the message is received, it will postMessage
+    // back and we'll repeat this with another iframe. If the first
+    // BroadcastChannel message is received by `bc1`, or if the second
+    // BroadcastChannel message is received by `bc1` or `bc2` in the first
+    // iframe, then the test should fail.
+
+    window.addEventListener("message", e => {
+      if(e.data == "iframe1-done") {
+        let iframe2 = document.createElement("iframe");
+        iframe2.src = "" "iframe2");
+        t.add_cleanup(() => { document.body.removeChild(iframe2) });
+        document.body.appendChild(iframe2);
+      } else if(e.data == "iframe2-done") {
+        resolve();
+      } else if(e.data == "fail") {
+        reject("One opaque origin received a message from the other");
+      } else {
+        reject("An unexpected error occurred");
+      }
+    });
+
+    let iframe1 = document.createElement("iframe");
+    iframe1.src = "" "iframe1");
+    t.add_cleanup(() => { document.body.removeChild(iframe1) });
+    document.body.appendChild(iframe1);
+    });
+}, "BroadcastChannel messages from opaque origins should be self-contained");
+//-->
+</script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log (291588 => 291589)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log	2022-03-21 23:46:48 UTC (rev 291589)
@@ -19,6 +19,7 @@
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/interface.any.js
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/origin.window.js
 /LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/sandbox.html

Modified: trunk/Source/WebCore/ChangeLog (291588 => 291589)


--- trunk/Source/WebCore/ChangeLog	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/ChangeLog	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1,3 +1,52 @@
+2022-03-21  Chris Dumez  <cdu...@apple.com>
+
+        BroadcastChannel instances in distinct opaque origins can communicate
+        https://bugs.webkit.org/show_bug.cgi?id=238090
+        <rdar://problem/90511155>
+
+        Reviewed by Alex Christensen.
+
+        The issue is that we would use a ClientOrigin to distinguish origins for BroadcastChannel,
+        which relies on SecurityOriginData internally. A unique/opaque SecurityOrigin becomes an empty
+        SecurityOriginData upon conversion. As a result, when comparing ClientOrigin objects from
+        unique SecurityOrigins, they would compare as equal.
+
+        To address the issue, I introduced a new PartitionedSecurityOrigin type which is similar
+        to ClientOrigin but stores SecurityOrigin objects internally, instead of SecurityOriginData
+        objects. PartitionedSecurityOrigin's operator==() is such that different SecurityOrigins
+        would not be equal but the same unique SecurityOrigin would be. I then used this new
+        PartitionedSecurityOrigin type as key in our HashMap on the WebProcess side instead of
+        ClientOrigin. This allows communication between several BroadcastChannels from the same
+        unique origin, while preventing communication between distinct opaque origins.
+
+        When the PartitionedSecurityOrigin contains an opaque security origin, we don't involve
+        the Network Process at all since the destination can only be in the same WebProcess.
+
+        Test: imported/w3c/web-platform-tests/webmessaging/broadcastchannel/opaque-origin.html
+
+        * Headers.cmake:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/BroadcastChannel.cpp:
+        (WebCore::shouldPartitionOrigin):
+        (WebCore::BroadcastChannel::MainThreadBridge::registerChannel):
+        (WebCore::BroadcastChannel::MainThreadBridge::unregisterChannel):
+        (WebCore::BroadcastChannel::MainThreadBridge::postMessage):
+        * dom/BroadcastChannelRegistry.h:
+        * loader/EmptyClients.cpp:
+        * page/PartitionedSecurityOrigin.h: Added.
+        (WebCore::PartitionedSecurityOrigin::PartitionedSecurityOrigin):
+        (WebCore::PartitionedSecurityOrigin::isHashTableDeletedValue const):
+        (WebCore::PartitionedSecurityOrigin::isHashTableEmptyValue const):
+        (WebCore::operator==):
+        (WTF::add):
+        (WTF::PartitionedSecurityOriginHash::hash):
+        (WTF::PartitionedSecurityOriginHash::equal):
+        (WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::emptyValue):
+        (WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::constructEmptyValue):
+        (WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::isEmptyValue):
+        (WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::peek):
+        (WTF::HashTraits<WebCore::PartitionedSecurityOrigin>::take):
+
 2022-03-21  Kate Cheney  <katherine_che...@apple.com>
 
         nj.gov: Background color incorrect for 'State Vehicles' section

Modified: trunk/Source/WebCore/Headers.cmake (291588 => 291589)


--- trunk/Source/WebCore/Headers.cmake	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/Headers.cmake	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1141,6 +1141,7 @@
     page/PageOverlay.h
     page/PageOverlayController.h
     page/PagePasteboardContext.h
+    page/PartitionedSecurityOrigin.h
     page/PerformanceLogging.h
     page/PerformanceLoggingClient.h
     page/PointerCaptureController.h

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (291588 => 291589)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1357,6 +1357,7 @@
 		4683DF412767E91A007D00C8 /* ShadowRealmGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4683DF3B2767DF26007D00C8 /* ShadowRealmGlobalScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		4688E98027B6B45000567CD2 /* CoreLocationGeolocationProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 4688E97F27B6B44400567CD2 /* CoreLocationGeolocationProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		4688EE3C26DD2610002AF5C4 /* CrossOriginMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4688EE3A26DD260C002AF5C4 /* CrossOriginMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		46893B8427E8D74C002CC13D /* PartitionedSecurityOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 46893B8327E8D716002CC13D /* PartitionedSecurityOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		46943DC92763F817004B610E /* SharedWorkerObjectIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46943DC72763F80E004B610E /* SharedWorkerObjectIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		46985F2327A4A6AD0097A32B /* SharedWorkerKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 46985F2227A4A6860097A32B /* SharedWorkerKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		469CCCFE269D021C006E0314 /* BroadcastChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 469CCCFC269D0202006E0314 /* BroadcastChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9288,6 +9289,7 @@
 		4688E97D27B6B44300567CD2 /* CoreLocationGeolocationProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreLocationGeolocationProvider.mm; sourceTree = "<group>"; };
 		4688E97F27B6B44400567CD2 /* CoreLocationGeolocationProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreLocationGeolocationProvider.h; sourceTree = "<group>"; };
 		4688EE3A26DD260C002AF5C4 /* CrossOriginMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrossOriginMode.h; sourceTree = "<group>"; };
+		46893B8327E8D716002CC13D /* PartitionedSecurityOrigin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PartitionedSecurityOrigin.h; sourceTree = "<group>"; };
 		468B8BDE25CC849300F67822 /* JSBaseAudioContextCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSBaseAudioContextCustom.cpp; sourceTree = "<group>"; };
 		46943DC72763F80E004B610E /* SharedWorkerObjectIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedWorkerObjectIdentifier.h; sourceTree = "<group>"; };
 		46985F2227A4A6860097A32B /* SharedWorkerKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedWorkerKey.h; sourceTree = "<group>"; };
@@ -24262,6 +24264,7 @@
 				F40DAAEE25D9F3BF0011B4FA /* PagePasteboardContext.h */,
 				371E65CD13661EED00BEEDB0 /* PageSerializer.cpp */,
 				371E65CB13661EDC00BEEDB0 /* PageSerializer.h */,
+				46893B8327E8D716002CC13D /* PartitionedSecurityOrigin.h */,
 				BC4A53282560563B0028C592 /* PDFImageCachingPolicy.h */,
 				7C72471E2516758800C363CD /* Performance+NavigationTiming.idl */,
 				7C72471C251674CE00C363CD /* Performance+PerformanceTimeline.idl */,
@@ -36602,6 +36605,7 @@
 				447958041643B49A001E0A7F /* ParsedContentType.h in Headers */,
 				5C4A0FDA25C3449A00D9EE97 /* ParsedRequestRange.h in Headers */,
 				536D5A23193E8E0C00CE4CAB /* ParsingUtilities.h in Headers */,
+				46893B8427E8D74C002CC13D /* PartitionedSecurityOrigin.h in Headers */,
 				F55B3DCA1251F12D003EF269 /* PasswordInputType.h in Headers */,
 				4B2708C70AF19EE40065127F /* Pasteboard.h in Headers */,
 				F40DAAEC25D9F25E0011B4FA /* PasteboardContext.h in Headers */,

Modified: trunk/Source/WebCore/dom/BroadcastChannel.cpp (291588 => 291589)


--- trunk/Source/WebCore/dom/BroadcastChannel.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/dom/BroadcastChannel.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -30,6 +30,7 @@
 #include "EventNames.h"
 #include "MessageEvent.h"
 #include "Page.h"
+#include "PartitionedSecurityOrigin.h"
 #include "SecurityOrigin.h"
 #include "SerializedScriptValue.h"
 #include "WorkerGlobalScope.h"
@@ -86,7 +87,7 @@
     WeakPtr<BroadcastChannel> m_broadcastChannel;
     const BroadcastChannelIdentifier m_identifier;
     const String m_name; // Main thread only.
-    ClientOrigin m_origin; // Main thread only.
+    std::optional<PartitionedSecurityOrigin> m_origin; // Main thread only.
 };
 
 BroadcastChannel::MainThreadBridge::MainThreadBridge(BroadcastChannel& channel, const String& name)
@@ -120,9 +121,9 @@
 void BroadcastChannel::MainThreadBridge::registerChannel()
 {
     ensureOnMainThread([this, contextIdentifier = m_broadcastChannel->scriptExecutionContext()->identifier()](auto& document) {
-        m_origin = { shouldPartitionOrigin(document) ? document.topOrigin().data() : document.securityOrigin().data(), document.securityOrigin().data() };
+        m_origin = PartitionedSecurityOrigin { shouldPartitionOrigin(document) ? document.topOrigin() : document.securityOrigin(), document.securityOrigin() };
         if (auto* page = document.page())
-            page->broadcastChannelRegistry().registerChannel(m_origin, m_name, m_identifier);
+            page->broadcastChannelRegistry().registerChannel(*m_origin, m_name, m_identifier);
         channelToContextIdentifier().add(m_identifier, contextIdentifier);
     });
 }
@@ -131,7 +132,7 @@
 {
     ensureOnMainThread([this](auto& document) {
         if (auto* page = document.page())
-            page->broadcastChannelRegistry().unregisterChannel(m_origin, m_name, m_identifier);
+            page->broadcastChannelRegistry().unregisterChannel(*m_origin, m_name, m_identifier);
         channelToContextIdentifier().remove(m_identifier);
     });
 }
@@ -144,7 +145,7 @@
             return;
 
         auto blobHandles = message->blobHandles();
-        page->broadcastChannelRegistry().postMessage(m_origin, m_name, m_identifier, WTFMove(message), [blobHandles = WTFMove(blobHandles)] {
+        page->broadcastChannelRegistry().postMessage(*m_origin, m_name, m_identifier, WTFMove(message), [blobHandles = WTFMove(blobHandles)] {
             // Keeps Blob data inside messageData alive until the message has been delivered.
         });
     });

Modified: trunk/Source/WebCore/dom/BroadcastChannelRegistry.h (291588 => 291589)


--- trunk/Source/WebCore/dom/BroadcastChannelRegistry.h	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/dom/BroadcastChannelRegistry.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -31,15 +31,15 @@
 
 namespace WebCore {
 
+struct PartitionedSecurityOrigin;
 class SerializedScriptValue;
-struct ClientOrigin;
 
 class BroadcastChannelRegistry : public RefCounted<BroadcastChannelRegistry> {
 public:
     virtual ~BroadcastChannelRegistry() { }
-    virtual void registerChannel(const ClientOrigin&, const String& name, BroadcastChannelIdentifier) = 0;
-    virtual void unregisterChannel(const ClientOrigin&, const String& name, BroadcastChannelIdentifier) = 0;
-    virtual void postMessage(const ClientOrigin&, const String& name, BroadcastChannelIdentifier source, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) = 0;
+    virtual void registerChannel(const PartitionedSecurityOrigin&, const String& name, BroadcastChannelIdentifier) = 0;
+    virtual void unregisterChannel(const PartitionedSecurityOrigin&, const String& name, BroadcastChannelIdentifier) = 0;
+    virtual void postMessage(const PartitionedSecurityOrigin&, const String& name, BroadcastChannelIdentifier source, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) = 0;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (291588 => 291589)


--- trunk/Source/WebCore/loader/EmptyClients.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1188,9 +1188,9 @@
 private:
     EmptyBroadcastChannelRegistry() = default;
 
-    void registerChannel(const ClientOrigin&, const String&, BroadcastChannelIdentifier) final { }
-    void unregisterChannel(const ClientOrigin&, const String&, BroadcastChannelIdentifier) final { }
-    void postMessage(const ClientOrigin&, const String&, BroadcastChannelIdentifier, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) final { }
+    void registerChannel(const PartitionedSecurityOrigin&, const String&, BroadcastChannelIdentifier) final { }
+    void unregisterChannel(const PartitionedSecurityOrigin&, const String&, BroadcastChannelIdentifier) final { }
+    void postMessage(const PartitionedSecurityOrigin&, const String&, BroadcastChannelIdentifier, Ref<SerializedScriptValue>&&, CompletionHandler<void()>&&) final { }
 };
 
 class EmptyWebLockRegistry final : public WebLockRegistry {

Added: trunk/Source/WebCore/page/PartitionedSecurityOrigin.h (0 => 291589)


--- trunk/Source/WebCore/page/PartitionedSecurityOrigin.h	                        (rev 0)
+++ trunk/Source/WebCore/page/PartitionedSecurityOrigin.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "SecurityOrigin.h"
+#include <wtf/HashTraits.h>
+#include <wtf/Hasher.h>
+#include <wtf/Ref.h>
+
+namespace WebCore {
+
+struct PartitionedSecurityOrigin {
+    PartitionedSecurityOrigin(Ref<SecurityOrigin>&& topOrigin, Ref<SecurityOrigin>&& clientOrigin)
+        : topOrigin(WTFMove(topOrigin))
+        , clientOrigin(WTFMove(clientOrigin))
+    { }
+
+    PartitionedSecurityOrigin(WTF::HashTableDeletedValueType)
+        : topOrigin(WTF::HashTableDeletedValue)
+        , clientOrigin(WTF::HashTableDeletedValue)
+    { }
+
+    PartitionedSecurityOrigin(WTF::HashTableEmptyValueType)
+        : topOrigin(WTF::HashTableEmptyValue)
+        , clientOrigin(WTF::HashTableEmptyValue)
+    { }
+
+    bool isHashTableDeletedValue() const { return topOrigin.isHashTableDeletedValue(); }
+    bool isHashTableEmptyValue() const { return topOrigin.isHashTableEmptyValue(); }
+
+    Ref<SecurityOrigin> topOrigin;
+    Ref<SecurityOrigin> clientOrigin;
+};
+
+inline bool operator==(const PartitionedSecurityOrigin& a, const PartitionedSecurityOrigin& b)
+{
+    return a.topOrigin->isSameOriginAs(b.topOrigin) && a.clientOrigin->isSameOriginAs(b.clientOrigin);
+}
+
+} // namespace WebCore
+
+namespace WTF {
+
+inline void add(Hasher& hasher, const WebCore::PartitionedSecurityOrigin& origin)
+{
+    add(hasher, origin.topOrigin.get(), origin.clientOrigin.get());
+}
+
+struct PartitionedSecurityOriginHash {
+    static unsigned hash(const WebCore::PartitionedSecurityOrigin& origin) { return computeHash(origin); }
+    static bool equal(const WebCore::PartitionedSecurityOrigin& a, const WebCore::PartitionedSecurityOrigin& b) { return a == b; }
+    static constexpr bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template<> struct DefaultHash<WebCore::PartitionedSecurityOrigin> : PartitionedSecurityOriginHash { };
+
+template<> struct HashTraits<WebCore::PartitionedSecurityOrigin> : SimpleClassHashTraits<WebCore::PartitionedSecurityOrigin> {
+    static constexpr bool emptyValueIsZero = true;
+    static WebCore::PartitionedSecurityOrigin emptyValue() { return HashTableEmptyValue; }
+
+    template <typename>
+    static void constructEmptyValue(WebCore::PartitionedSecurityOrigin& slot)
+    {
+        new (NotNull, std::addressof(slot)) WebCore::PartitionedSecurityOrigin(HashTableEmptyValue);
+    }
+
+    static constexpr bool hasIsEmptyValueFunction = true;
+    static bool isEmptyValue(const WebCore::PartitionedSecurityOrigin& value) { return value.isHashTableEmptyValue(); }
+
+    using PeekType = std::optional<WebCore::PartitionedSecurityOrigin>;
+    static PeekType peek(const WebCore::PartitionedSecurityOrigin& value) { return isEmptyValue(value) ? std::nullopt : std::optional { value }; }
+
+    using TakeType = std::optional<WebCore::PartitionedSecurityOrigin>;
+    static TakeType take(WebCore::PartitionedSecurityOrigin&& value) { return isEmptyValue(value) ? std::nullopt : std::optional { WTFMove(value) }; }
+};
+
+} // namespace WTF

Modified: trunk/Source/WebKit/ChangeLog (291588 => 291589)


--- trunk/Source/WebKit/ChangeLog	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/ChangeLog	2022-03-21 23:46:48 UTC (rev 291589)
@@ -1,3 +1,37 @@
+2022-03-21  Chris Dumez  <cdu...@apple.com>
+
+        BroadcastChannel instances in distinct opaque origins can communicate
+        https://bugs.webkit.org/show_bug.cgi?id=238090
+        <rdar://problem/90511155>
+
+        Reviewed by Alex Christensen.
+
+        The issue is that we would use a ClientOrigin to distinguish origins for BroadcastChannel,
+        which relies on SecurityOriginData internally. A unique/opaque SecurityOrigin becomes an empty
+        SecurityOriginData upon conversion. As a result, when comparing ClientOrigin objects from
+        unique SecurityOrigins, they would compare as equal.
+
+        To address the issue, I introduced a new PartitionedSecurityOrigin type which is similar
+        to ClientOrigin but stores SecurityOrigin objects internally, instead of SecurityOriginData
+        objects. PartitionedSecurityOrigin's operator==() is such that different SecurityOrigins
+        would not be equal but the same unique SecurityOrigin would be. I then used this new
+        PartitionedSecurityOrigin type as key in our HashMap on the WebProcess side instead of
+        ClientOrigin. This allows communication between several BroadcastChannels from the same
+        unique origin, while preventing communication between distinct opaque origins.
+
+        When the PartitionedSecurityOrigin contains an opaque security origin, we don't involve
+        the Network Process at all since the destination can only be in the same WebProcess.
+
+        * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp:
+        (WebKit::toClientOrigin):
+        (WebKit::WebBroadcastChannelRegistry::registerChannel):
+        (WebKit::WebBroadcastChannelRegistry::unregisterChannel):
+        (WebKit::WebBroadcastChannelRegistry::postMessage):
+        (WebKit::WebBroadcastChannelRegistry::postMessageLocally):
+        (WebKit::WebBroadcastChannelRegistry::postMessageToRemote):
+        (WebKit::WebBroadcastChannelRegistry::networkProcessCrashed):
+        * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h:
+
 2022-03-21  Brent Fulgham  <bfulg...@apple.com>
 
         Disable the <model> element in Captive Portal mode.

Modified: trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp (291588 => 291589)


--- trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "NetworkBroadcastChannelRegistry.h"
 
+#include "NetworkProcessProxyMessages.h"
 #include "WebBroadcastChannelRegistryMessages.h"
 #include <WebCore/MessageWithMessagePorts.h>
 #include <wtf/CallbackAggregator.h>
@@ -32,10 +33,31 @@
 
 namespace WebKit {
 
-NetworkBroadcastChannelRegistry::NetworkBroadcastChannelRegistry() = default;
+#define REGISTRY_MESSAGE_CHECK(assertion) REGISTRY_MESSAGE_CHECK_COMPLETION(assertion, (void)0)
+#define REGISTRY_MESSAGE_CHECK_COMPLETION(assertion, completion) do { \
+    ASSERT(assertion); \
+    if (UNLIKELY(!(assertion))) { \
+        if (auto webProcessIdentifier = m_networkProcess->webProcessIdentifierForConnection(connection)) \
+            m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::TerminateWebProcess(webProcessIdentifier), 0); \
+        { completion; } \
+        return; \
+    } \
+} while (0)
 
+static bool isValidClientOrigin(const WebCore::ClientOrigin& clientOrigin)
+{
+    return !clientOrigin.topOrigin.isEmpty() && !clientOrigin.clientOrigin.isEmpty();
+}
+
+NetworkBroadcastChannelRegistry::NetworkBroadcastChannelRegistry(NetworkProcess& networkProcess)
+    : m_networkProcess(networkProcess)
+{
+}
+
 void NetworkBroadcastChannelRegistry::registerChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name)
 {
+    REGISTRY_MESSAGE_CHECK(isValidClientOrigin(origin));
+
     auto& channelsForOrigin = m_broadcastChannels.ensure(origin, [] { return NameToConnectionIdentifiersMap { }; }).iterator->value;
     auto& connectionIdentifiersForName = channelsForOrigin.ensure(name, [] { return Vector<IPC::Connection::UniqueID> { }; }).iterator->value;
     ASSERT(!connectionIdentifiersForName.contains(connection.uniqueID()));
@@ -44,6 +66,8 @@
 
 void NetworkBroadcastChannelRegistry::unregisterChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name)
 {
+    REGISTRY_MESSAGE_CHECK(isValidClientOrigin(origin));
+
     auto channelsForOriginIterator = m_broadcastChannels.find(origin);
     ASSERT(channelsForOriginIterator != m_broadcastChannels.end());
     if (channelsForOriginIterator == m_broadcastChannels.end())
@@ -59,6 +83,8 @@
 
 void NetworkBroadcastChannelRegistry::postMessage(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
 {
+    REGISTRY_MESSAGE_CHECK_COMPLETION(isValidClientOrigin(origin), completionHandler());
+
     auto channelsForOriginIterator = m_broadcastChannels.find(origin);
     ASSERT(channelsForOriginIterator != m_broadcastChannels.end());
     if (channelsForOriginIterator == m_broadcastChannels.end())
@@ -101,4 +127,7 @@
         m_broadcastChannels.remove(originToRemove);
 }
 
+#undef REGISTRY_MESSAGE_CHECK
+#undef REGISTRY_MESSAGE_CHECK_COMPLETION
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h (291588 => 291589)


--- trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -36,10 +36,12 @@
 
 namespace WebKit {
 
+class NetworkProcess;
+
 class NetworkBroadcastChannelRegistry {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    NetworkBroadcastChannelRegistry();
+    explicit NetworkBroadcastChannelRegistry(NetworkProcess&);
 
     void removeConnection(IPC::Connection&);
 
@@ -50,6 +52,7 @@
     void postMessage(IPC::Connection&, const WebCore::ClientOrigin&, const String& name, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
 
 private:
+    Ref<NetworkProcess> m_networkProcess;
     using NameToConnectionIdentifiersMap = HashMap<String, Vector<IPC::Connection::UniqueID>>;
     HashMap<WebCore::ClientOrigin, NameToConnectionIdentifiersMap> m_broadcastChannels;
 };

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (291588 => 291589)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -2552,6 +2552,15 @@
         session->storageManager().stopReceivingMessageFromConnection(connection);
 }
 
+WebCore::ProcessIdentifier NetworkProcess::webProcessIdentifierForConnection(IPC::Connection& connection) const
+{
+    for (auto& [processIdentifier, webConnection] : m_webProcessConnections) {
+        if (&webConnection->connection() == &connection)
+            return processIdentifier;
+    }
+    return { };
+}
+
 NetworkConnectionToWebProcess* NetworkProcess::webProcessConnection(ProcessIdentifier identifier) const
 {
     return m_webProcessConnections.get(identifier);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (291588 => 291589)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -332,6 +332,7 @@
     const OptionSet<NetworkCache::CacheOption>& cacheOptions() const { return m_cacheOptions; }
 
     NetworkConnectionToWebProcess* webProcessConnection(WebCore::ProcessIdentifier) const;
+    WebCore::ProcessIdentifier webProcessIdentifierForConnection(IPC::Connection&) const;
     WebCore::MessagePortChannelRegistry& messagePortChannelRegistry() { return m_messagePortChannelRegistry; }
 
     void setServiceWorkerFetchTimeoutForTesting(Seconds, CompletionHandler<void()>&&);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp (291588 => 291589)


--- trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -138,7 +138,7 @@
 #endif
     , m_privateClickMeasurement(managerOrProxy(*this, networkProcess, parameters))
     , m_privateClickMeasurementDebugModeEnabled(parameters.enablePrivateClickMeasurementDebugMode)
-    , m_broadcastChannelRegistry(makeUniqueRef<NetworkBroadcastChannelRegistry>())
+    , m_broadcastChannelRegistry(makeUniqueRef<NetworkBroadcastChannelRegistry>(networkProcess))
     , m_testSpeedMultiplier(parameters.testSpeedMultiplier)
     , m_allowsServerPreconnect(parameters.allowsServerPreconnect)
     , m_shouldRunServiceWorkersOnMainThreadForTesting(parameters.shouldRunServiceWorkersOnMainThreadForTesting)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp (291588 => 291589)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -40,17 +40,30 @@
     return WebProcess::singleton().ensureNetworkProcessConnection().connection();
 }
 
-void WebBroadcastChannelRegistry::registerChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
+// Unique origins are only stored in process in m_channelsPerOrigin and never sent to the NetworkProcess as a ClientOrigin.
+// The identity of unique origins wouldn't be preserved when serializing them as a SecurityOriginData (via ClientOrigin).
+// Since BroadcastChannels from a unique origin can only communicate with other BroadcastChannels from the same unique origin,
+// the destination channels have to be within the same WebProcess anyway.
+static std::optional<WebCore::ClientOrigin> toClientOrigin(const WebCore::PartitionedSecurityOrigin& origin)
 {
+    if (origin.topOrigin->isUnique() || origin.clientOrigin->isUnique())
+        return std::nullopt;
+    return WebCore::ClientOrigin { origin.topOrigin->data(), origin.clientOrigin->data() };
+}
+
+void WebBroadcastChannelRegistry::registerChannel(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
+{
     auto& channelsForOrigin = m_channelsPerOrigin.ensure(origin, [] { return HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>> { }; }).iterator->value;
     auto& channelsForName = channelsForOrigin.ensure(name, [] { return Vector<WebCore::BroadcastChannelIdentifier> { }; }).iterator->value;
     channelsForName.append(identifier);
 
-    if (channelsForName.size() == 1)
-        networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { origin, name }, 0);
+    if (channelsForName.size() == 1) {
+        if (auto clientOrigin = toClientOrigin(origin))
+            networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { *clientOrigin, name }, 0);
+    }
 }
 
-void WebBroadcastChannelRegistry::unregisterChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
+void WebBroadcastChannelRegistry::unregisterChannel(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
 {
     auto channelsPerOriginIterator = m_channelsPerOrigin.find(origin);
     if (channelsPerOriginIterator == m_channelsPerOrigin.end())
@@ -68,20 +81,22 @@
         return;
 
     channelsForOrigin.remove(channelsForOriginIterator);
-    networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::UnregisterChannel { origin, name }, 0);
+    if (auto clientOrigin = toClientOrigin(origin))
+        networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::UnregisterChannel { *clientOrigin, name }, 0);
 
     if (channelsForOrigin.isEmpty())
         m_channelsPerOrigin.remove(channelsPerOriginIterator);
 }
 
-void WebBroadcastChannelRegistry::postMessage(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler)
+void WebBroadcastChannelRegistry::postMessage(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler)
 {
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
     postMessageLocally(origin, name, source, message.copyRef(), callbackAggregator.copyRef());
-    networkProcessConnection().sendWithAsyncReply(Messages::NetworkBroadcastChannelRegistry::PostMessage { origin, name, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, [callbackAggregator] { }, 0);
+    if (auto clientOrigin = toClientOrigin(origin))
+        networkProcessConnection().sendWithAsyncReply(Messages::NetworkBroadcastChannelRegistry::PostMessage { *clientOrigin, name, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, [callbackAggregator] { }, 0);
 }
 
-void WebBroadcastChannelRegistry::postMessageLocally(const WebCore::ClientOrigin& origin, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&& message, Ref<WTF::CallbackAggregator>&& callbackAggregator)
+void WebBroadcastChannelRegistry::postMessageLocally(const WebCore::PartitionedSecurityOrigin& origin, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&& message, Ref<WTF::CallbackAggregator>&& callbackAggregator)
 {
     auto channelsPerOriginIterator = m_channelsPerOrigin.find(origin);
     if (channelsPerOriginIterator == m_channelsPerOrigin.end())
@@ -100,9 +115,10 @@
     }
 }
 
-void WebBroadcastChannelRegistry::postMessageToRemote(const WebCore::ClientOrigin& origin, const String& name, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
+void WebBroadcastChannelRegistry::postMessageToRemote(const WebCore::ClientOrigin& clientOrigin, const String& name, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
 {
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+    WebCore::PartitionedSecurityOrigin origin { clientOrigin.topOrigin.securityOrigin(), clientOrigin.clientOrigin.securityOrigin() };
     postMessageLocally(origin, name, std::nullopt, *message.message, callbackAggregator.copyRef());
 }
 
@@ -109,8 +125,11 @@
 void WebBroadcastChannelRegistry::networkProcessCrashed()
 {
     for (auto& [origin, channelsForOrigin] : m_channelsPerOrigin) {
+        auto clientOrigin = toClientOrigin(origin);
+        if (!clientOrigin)
+            continue;
         for (auto& name : channelsForOrigin.keys())
-            networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { origin, name }, 0);
+            networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { *clientOrigin, name }, 0);
     }
 }
 

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h (291588 => 291589)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -28,6 +28,8 @@
 #include "Connection.h"
 #include <WebCore/BroadcastChannelRegistry.h>
 #include <WebCore/ClientOrigin.h>
+#include <WebCore/PartitionedSecurityOrigin.h>
+#include <WebCore/SecurityOrigin.h>
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
 
@@ -48,9 +50,9 @@
         return adoptRef(*new WebBroadcastChannelRegistry);
     }
 
-    void registerChannel(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
-    void unregisterChannel(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
-    void postMessage(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final;
+    void registerChannel(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
+    void unregisterChannel(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
+    void postMessage(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final;
 
     void networkProcessCrashed();
 
@@ -60,9 +62,9 @@
     WebBroadcastChannelRegistry() = default;
 
     void postMessageToRemote(const WebCore::ClientOrigin&, const String& name, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
-    void postMessageLocally(const WebCore::ClientOrigin&, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&&, Ref<WTF::CallbackAggregator>&&);
+    void postMessageLocally(const WebCore::PartitionedSecurityOrigin&, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&&, Ref<WTF::CallbackAggregator>&&);
 
-    HashMap<WebCore::ClientOrigin, HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>>> m_channelsPerOrigin;
+    HashMap<WebCore::PartitionedSecurityOrigin, HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>>> m_channelsPerOrigin;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKitLegacy/ChangeLog (291588 => 291589)


--- trunk/Source/WebKitLegacy/ChangeLog	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKitLegacy/ChangeLog	2022-03-21 23:46:48 UTC (rev 291589)
@@ -7,6 +7,20 @@
 
         * PlatformMac.cmake:
 
+2022-03-21  Chris Dumez  <cdu...@apple.com>
+
+        BroadcastChannel instances in distinct opaque origins can communicate
+        https://bugs.webkit.org/show_bug.cgi?id=238090
+        <rdar://problem/90511155>
+
+        Reviewed by Alex Christensen.
+
+        * WebCoreSupport/WebBroadcastChannelRegistry.cpp:
+        (WebBroadcastChannelRegistry::registerChannel):
+        (WebBroadcastChannelRegistry::unregisterChannel):
+        (WebBroadcastChannelRegistry::postMessage):
+        * WebCoreSupport/WebBroadcastChannelRegistry.h:
+
 2022-03-08  Chris Dumez  <cdu...@apple.com>
 
         Optimize further the passing of data across threads

Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.cpp (291588 => 291589)


--- trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2022-03-21 23:46:48 UTC (rev 291589)
@@ -44,7 +44,7 @@
     return registry;
 }
 
-void WebBroadcastChannelRegistry::registerChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
+void WebBroadcastChannelRegistry::registerChannel(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
 {
     ASSERT(isMainThread());
     auto& channelsForOrigin = m_channels.ensure(origin, [] { return NameToChannelIdentifiersMap { }; }).iterator->value;
@@ -53,7 +53,7 @@
     channelsForName.append(identifier);
 }
 
-void WebBroadcastChannelRegistry::unregisterChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
+void WebBroadcastChannelRegistry::unregisterChannel(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
 {
     ASSERT(isMainThread());
     auto channelsForOriginIterator = m_channels.find(origin);
@@ -66,7 +66,7 @@
     channelsForNameIterator->value.removeFirst(identifier);
 }
 
-void WebBroadcastChannelRegistry::postMessage(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler)
+void WebBroadcastChannelRegistry::postMessage(const WebCore::PartitionedSecurityOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(isMainThread());
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));

Modified: trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.h (291588 => 291589)


--- trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.h	2022-03-21 23:39:22 UTC (rev 291588)
+++ trunk/Source/WebKitLegacy/WebCoreSupport/WebBroadcastChannelRegistry.h	2022-03-21 23:46:48 UTC (rev 291589)
@@ -24,7 +24,7 @@
  */
 
 #include <WebCore/BroadcastChannelRegistry.h>
-#include <WebCore/ClientOrigin.h>
+#include <WebCore/PartitionedSecurityOrigin.h>
 #include <wtf/Forward.h>
 #include <wtf/WeakPtr.h>
 
@@ -34,13 +34,13 @@
 public:
     static Ref<WebBroadcastChannelRegistry> getOrCreate(bool privateSession);
 
-    void registerChannel(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
-    void unregisterChannel(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
-    void postMessage(const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final;
+    void registerChannel(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
+    void unregisterChannel(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier) final;
+    void postMessage(const WebCore::PartitionedSecurityOrigin&, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&&, CompletionHandler<void()>&&) final;
 
 private:
     WebBroadcastChannelRegistry() = default;
 
     using NameToChannelIdentifiersMap = HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>>;
-    HashMap<WebCore::ClientOrigin, NameToChannelIdentifiersMap> m_channels;
+    HashMap<WebCore::PartitionedSecurityOrigin, NameToChannelIdentifiersMap> m_channels;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to