From: uazo <uazo@users.noreply.github.com>
Date: Wed, 13 Jul 2022 14:51:09 +0000
Subject: Partition Blink memory cache

Blink's in-memory cache is not partitioned (see also: http://crbug.com/1127971)
This patch partitions it by the top-level site.
This mitigation is effective in case the rendering process is re-used, because
on such case the cache would be re-used as well and transfer information between
different contexts.

See also:
* https://github.com/bromite/bromite/pull/2173

Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
 .../core/html/parser/html_srcset_parser.cc    |  2 +-
 .../core/inspector/inspector_network_agent.cc |  2 +-
 .../core/inspector/inspector_page_agent.cc    |  4 ++--
 .../renderer/core/loader/image_loader.cc      |  3 ++-
 .../platform/loader/fetch/memory_cache.cc     |  7 ++-----
 .../platform/loader/fetch/memory_cache.h      |  4 ++--
 .../platform/loader/fetch/resource_fetcher.cc | 21 ++++++++++++-------
 .../platform/loader/fetch/resource_fetcher.h  |  3 ++-
 8 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
--- a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
@@ -413,7 +413,7 @@ static unsigned AvoidDownloadIfHigherDensityResourceIsInCache(
     KURL url = document->CompleteURL(
         StripLeadingAndTrailingHTMLSpaces(image_candidates[i]->Url()));
     if (MemoryCache::Get()->ResourceForURL(
-            url, document->Fetcher()->GetCacheIdentifier(url)) ||
+            url, document->Fetcher()->GetCacheIdentifier(url, document->TopFrameOrigin())) ||
         url.ProtocolIsData())
       return i;
   }
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
--- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -2252,7 +2252,7 @@ bool InspectorNetworkAgent::FetchResourceContent(Document* document,
   Resource* cached_resource = document->Fetcher()->CachedResource(url);
   if (!cached_resource) {
     cached_resource = MemoryCache::Get()->ResourceForURL(
-        url, document->Fetcher()->GetCacheIdentifier(url));
+        url, document->Fetcher()->GetCacheIdentifier(url, document->TopFrameOrigin()));
   }
   if (cached_resource && InspectorPageAgent::CachedResourceContent(
                              cached_resource, content, base64_encoded))
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
--- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -167,9 +167,9 @@ Resource* CachedResource(LocalFrame* frame,
   if (!document)
     return nullptr;
   Resource* cached_resource = document->Fetcher()->CachedResource(url);
-  if (!cached_resource) {
+  if (!cached_resource && document->TopFrameOrigin()) {
     cached_resource = MemoryCache::Get()->ResourceForURL(
-        url, document->Fetcher()->GetCacheIdentifier(url));
+        url, document->Fetcher()->GetCacheIdentifier(url, document->TopFrameOrigin()));
   }
   if (!cached_resource)
     cached_resource = loader->ResourceForURL(url);
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc
--- a/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -729,7 +729,8 @@ bool ImageLoader::ShouldLoadImmediately(const KURL& url) const {
   // content when style recalc is over and DOM mutation is allowed again.
   if (!url.IsNull()) {
     Resource* resource = MemoryCache::Get()->ResourceForURL(
-        url, element_->GetDocument().Fetcher()->GetCacheIdentifier(url));
+        url, element_->GetDocument().Fetcher()->GetCacheIdentifier(url,
+                element_->GetDocument().TopFrameOrigin()));
 
     if (resource && !resource->ErrorOccurred() &&
         CanReuseFromListOfAvailableImages(
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -198,7 +198,7 @@ void MemoryCache::RemoveInternal(ResourceMap* resource_map,
 }
 
 bool MemoryCache::Contains(const Resource* resource) const {
-  if (!resource || resource->Url().IsEmpty())
+  if (!resource || resource->Url().IsEmpty() || resource->CacheIdentifier().empty())
     return false;
 
   const auto resource_maps_it =
@@ -214,12 +214,9 @@ bool MemoryCache::Contains(const Resource* resource) const {
   return resource == resources_it->value->GetResource();
 }
 
-Resource* MemoryCache::ResourceForURL(const KURL& resource_url) const {
-  return ResourceForURL(resource_url, DefaultCacheIdentifier());
-}
-
 Resource* MemoryCache::ResourceForURL(const KURL& resource_url,
                                       const String& cache_identifier) const {
+  if (cache_identifier.empty()) return nullptr;
   DCHECK(WTF::IsMainThread());
   if (!resource_url.IsValid() || resource_url.IsNull())
     return nullptr;
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.h b/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.h
@@ -116,9 +116,7 @@ class PLATFORM_EXPORT MemoryCache final : public GarbageCollected<MemoryCache>,
     TypeStatistic other;
   };
 
-  Resource* ResourceForURL(const KURL&) const;
   Resource* ResourceForURL(const KURL&, const String& cache_identifier) const;
-  HeapVector<Member<Resource>> ResourcesForURL(const KURL&) const;
 
   void Add(Resource*);
   void Remove(Resource*);
@@ -163,6 +161,8 @@ class PLATFORM_EXPORT MemoryCache final : public GarbageCollected<MemoryCache>,
       base::MemoryPressureListener::MemoryPressureLevel) override;
 
  private:
+   HeapVector<Member<Resource>> ResourcesForURL(const KURL&) const;
+
   enum PruneStrategy {
     // Automatically decide how much to prune.
     kAutomaticPrune,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -657,7 +657,8 @@ Resource* ResourceFetcher::CreateResourceForStaticData(
   if (!archive_ && factory.GetType() == ResourceType::kRaw)
     return nullptr;
 
-  const String cache_identifier = GetCacheIdentifier(url);
+  const String cache_identifier = GetCacheIdentifier(url,
+                          params.GetResourceRequest().TopFrameOrigin());
   // Most off-main-thread resource fetches use Resource::kRaw and don't reach
   // this point, but off-main-thread module fetches might.
   if (IsMainThread()) {
@@ -1116,7 +1117,9 @@ Resource* ResourceFetcher::RequestResource(FetchParameters& params,
         resource = nullptr;
       } else {
         resource = MemoryCache::Get()->ResourceForURL(
-            params.Url(), GetCacheIdentifier(params.Url()));
+            params.Url(),
+            GetCacheIdentifier(params.Url(),
+              params.GetResourceRequest().TopFrameOrigin()));
       }
       if (resource) {
         policy = DetermineRevalidationPolicy(resource_type, params, *resource,
@@ -1324,7 +1327,8 @@ Resource* ResourceFetcher::CreateResourceForLoading(
     const FetchParameters& params,
     const ResourceFactory& factory) {
   const String cache_identifier =
-      GetCacheIdentifier(params.GetResourceRequest().Url());
+      GetCacheIdentifier(params.GetResourceRequest().Url(),
+        params.GetResourceRequest().TopFrameOrigin());
   if (!base::FeatureList::IsEnabled(
           blink::features::kScopeMemoryCachePerContext)) {
     DCHECK(!IsMainThread() || params.IsStaleRevalidation() ||
@@ -2213,13 +2217,16 @@ void ResourceFetcher::UpdateAllImageResourcePriorities() {
   to_be_removed.clear();
 }
 
-String ResourceFetcher::GetCacheIdentifier(const KURL& url) const {
+String ResourceFetcher::GetCacheIdentifier(const KURL& url,
+              scoped_refptr<const blink::SecurityOrigin> origin) const {
+  String origin_url = origin ? origin->ToRawString() : "";
+
   if (properties_->GetControllerServiceWorkerMode() !=
       mojom::ControllerServiceWorkerMode::kNoController) {
-    return String::Number(properties_->ServiceWorkerId());
+    return origin_url + " " + String::Number(properties_->ServiceWorkerId());
   }
   if (properties_->WebBundlePhysicalUrl().IsValid())
-    return properties_->WebBundlePhysicalUrl().GetString();
+    return origin_url + " " + properties_->WebBundlePhysicalUrl().GetString();
 
   // Requests that can be satisfied via `archive_` (i.e. MHTML) or
   // `subresource_web_bundles_` should not participate in the global caching,
@@ -2231,7 +2238,7 @@ String ResourceFetcher::GetCacheIdentifier(const KURL& url) const {
   if (bundle)
     return bundle->GetCacheIdentifier();
 
-  return MemoryCache::DefaultCacheIdentifier();
+  return origin_url;
 }
 
 absl::optional<base::UnguessableToken>
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -252,7 +252,8 @@ class PLATFORM_EXPORT ResourceFetcher
                          uint32_t inflight_keepalive_bytes);
   blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker() const;
 
-  String GetCacheIdentifier(const KURL& url) const;
+  String GetCacheIdentifier(const KURL& url,
+    scoped_refptr<const blink::SecurityOrigin> cache_identifier) const;
 
   // If `url` exists as a resource in a subresource bundle in this frame,
   // returns its UnguessableToken; otherwise, returns absl::nullopt.
--
2.25.1
