Origin-keyed agent clusters: make COI imply origin-keying

All other observable impacts of origin-keying, namely the impact on
postMessage and document.domain, are already in place for cross-origin
isolated agent clusters. So we only need to update the
window.originAgentCluster getter.

Fixed: 1163687
Change-Id: Ie10f26def8de2046d2b0ce69b37d56b3c89db57b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2630231
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844135}
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 0cb413a..5b52f84 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5873,15 +5873,10 @@
     return;
   }
 
-  if (RuntimeEnabledFeatures::OriginIsolationHeaderEnabled(dom_window_) &&
-      dom_window_->GetAgent()->IsOriginKeyed()) {
-    AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
-        mojom::blink::ConsoleMessageSource::kSecurity,
-        mojom::blink::ConsoleMessageLevel::kWarning,
-        "document.domain mutation is ignored because the surrounding agent "
-        "cluster is origin-keyed."));
-    return;
-  }
+  // We technically only need to IsOriginKeyed(), as IsCrossOriginIsolated()
+  // implies IsOriginKeyed(). (The spec only checks "is origin-keyed".) But,
+  // we'll check both, in order to give warning messages that are more specific
+  // about the cause. Note: this means the order of the checks is important.
 
   if (RuntimeEnabledFeatures::CrossOriginIsolationEnabled() &&
       Agent::IsCrossOriginIsolated()) {
@@ -5893,6 +5888,16 @@
     return;
   }
 
+  if (RuntimeEnabledFeatures::OriginIsolationHeaderEnabled(dom_window_) &&
+      dom_window_->GetAgent()->IsOriginKeyed()) {
+    AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+        mojom::blink::ConsoleMessageSource::kSecurity,
+        mojom::blink::ConsoleMessageLevel::kWarning,
+        "document.domain mutation is ignored because the surrounding agent "
+        "cluster is origin-keyed."));
+    return;
+  }
+
   if (GetFrame()) {
     UseCounter::Count(*this,
                       dom_window_->GetSecurityOrigin()->Port() == 0
diff --git a/third_party/blink/renderer/core/execution_context/agent.cc b/third_party/blink/renderer/core/execution_context/agent.cc
index 7370adbd..f78f0e7 100644
--- a/third_party/blink/renderer/core/execution_context/agent.cc
+++ b/third_party/blink/renderer/core/execution_context/agent.cc
@@ -53,18 +53,23 @@
 }
 
 bool Agent::IsOriginKeyed() {
+  if (IsCrossOriginIsolated()) {
+    return true;
+  }
+
 #if DCHECK_IS_ON()
-  DCHECK(is_origin_keyed_set_);
+  DCHECK(is_explicitly_origin_keyed_set_);
 #endif
-  return is_origin_keyed_;
+  return is_explicitly_origin_keyed_;
 }
 
-void Agent::SetIsOriginKeyed(bool value) {
+void Agent::SetIsExplicitlyOriginKeyed(bool value) {
 #if DCHECK_IS_ON()
-  DCHECK(!is_origin_keyed_set_ || value == is_origin_keyed_);
-  is_origin_keyed_set_ = true;
+  DCHECK(!is_explicitly_origin_keyed_set_ ||
+         value == is_explicitly_origin_keyed_);
+  is_explicitly_origin_keyed_set_ = true;
 #endif
-  is_origin_keyed_ = value;
+  is_explicitly_origin_keyed_ = value;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/execution_context/agent.h b/third_party/blink/renderer/core/execution_context/agent.h
index 5eed250..fe5548ef 100644
--- a/third_party/blink/renderer/core/execution_context/agent.h
+++ b/third_party/blink/renderer/core/execution_context/agent.h
@@ -73,15 +73,19 @@
   // URL to create an iframe, would have an origin-keyed data: URL Agent,
   // plus a site-keyed outer page Agent, both in the same process.
   bool IsOriginKeyed();
-  void SetIsOriginKeyed(bool value);
+
+  // This sets whether the agent cluster is explicitly requested to be
+  // origin-keyed via the Origin-Agent-Cluster header. It can also be
+  // implicitly origin-keyed if it is in a cross-origin isolated agent cluster.
+  void SetIsExplicitlyOriginKeyed(bool value);
 
  private:
   scoped_refptr<scheduler::EventLoop> event_loop_;
   const base::UnguessableToken cluster_id_;
-  bool is_origin_keyed_ = false;
+  bool is_explicitly_origin_keyed_ = false;
 
 #if DCHECK_IS_ON()
-  bool is_origin_keyed_set_ = false;
+  bool is_explicitly_origin_keyed_set_ = false;
 #endif
 };
 
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 294cdff..9782287a 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1802,7 +1802,7 @@
     // architecture.
     if (!Document::ShouldInheritSecurityOriginFromOwner(Url()) &&
         commit_reason_ != CommitReason::kJavascriptUrl) {
-      agent->SetIsOriginKeyed(origin_agent_cluster_);
+      agent->SetIsExplicitlyOriginKeyed(origin_agent_cluster_);
     }
   } else {
     if (frame_->GetSettings()->GetShouldReuseGlobalForUnownedMainFrame() &&
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html
new file mode 100644
index 0000000..e10d3452
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>window.originAgentCluster must be implied by cross-origin isolation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe src="//{{domains[www1]}}:{{location[port]}}/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html"></iframe>
+
+<div id="log"></div>
+
+<script type="module">
+import { testGetter } from "../resources/helpers.mjs";
+
+setup({ explicit_done: true });
+
+window.onload = () => {
+  // Cross-origin isolated pages are always origin-keyed.
+  testGetter(self, true, "self");
+
+  // Child frames of cross-origin isolated pages must also be cross-origin
+  // isolated, and thus also origin-keyed. Make sure the implementation doesn't
+  // treat them specially in some wierd way, for the purposes of this
+  // implication.
+  testGetter(0, true, "child");
+
+  done();
+};
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html.headers b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html.headers
new file mode 100644
index 0000000..5f8621ef8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/getter-special-cases/cross-origin-isolated.sub.https.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Opener-Policy: same-origin
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html
new file mode 100644
index 0000000..7cbd89b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>A page with COEP set that will respond when asked</title>
+
+<script type="module" src="send-header-page-script.mjs"></script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html.headers b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html.headers
new file mode 100644
index 0000000..4e798cd9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/origin-keyed-agent-clusters/resources/coep-frame.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Resource-Policy: cross-origin