git: 382d7828063a - main - www/qt6-webengine: Address multiple vulnerabilities

From: Jason E. Hale <jhale_at_FreeBSD.org>
Date: Sat, 07 Dec 2024 15:59:46 UTC
The branch main has been updated by jhale:

URL: https://cgit.FreeBSD.org/ports/commit/?id=382d7828063a451aed6fdba400cd642c9f1e84df

commit 382d7828063a451aed6fdba400cd642c9f1e84df
Author:     Jason E. Hale <jhale@FreeBSD.org>
AuthorDate: 2024-12-07 06:11:51 +0000
Commit:     Jason E. Hale <jhale@FreeBSD.org>
CommitDate: 2024-12-07 15:59:31 +0000

    www/qt6-webengine: Address multiple vulnerabilities
    
    Includes security patches up to Chromium 131.0.6778.108.
    
    MFH:            2024Q4
    Security:       c2fd83e4-b450-11ef-b680-4ccc6adda413
---
 www/qt6-webengine/Makefile                    |    2 +-
 www/qt6-webengine/files/patch-security-rollup | 1921 ++++++++++++++++++++++++-
 2 files changed, 1918 insertions(+), 5 deletions(-)

diff --git a/www/qt6-webengine/Makefile b/www/qt6-webengine/Makefile
index 352dcaf77694..59ef4d840c56 100644
--- a/www/qt6-webengine/Makefile
+++ b/www/qt6-webengine/Makefile
@@ -12,7 +12,7 @@
 
 PORTNAME?=	webengine
 DISTVERSION=	${QT6_VERSION}
-PORTREVISION?=	2 # Master port for print/qt6-pdf. Please keep this line.
+PORTREVISION?=	3 # Master port for print/qt6-pdf. Please keep this line.
 CATEGORIES?=	www
 PKGNAMEPREFIX=	qt6-
 
diff --git a/www/qt6-webengine/files/patch-security-rollup b/www/qt6-webengine/files/patch-security-rollup
index 651d5dacb2e1..ee21cc53c094 100644
--- a/www/qt6-webengine/files/patch-security-rollup
+++ b/www/qt6-webengine/files/patch-security-rollup
@@ -1,10 +1,12 @@
 Security fixes applied to the 118-based branch [1] after Qt 6.7.3 release.
 
-Includes fixes between [2] and [3].
+Includes fixes between [2] and [3]. [4] has been redacted, since it disrupts
+our main patches, is not a security fix, and only applies to iOS.
 
 [1] https://code.qt.io/cgit/qt/qtwebengine-chromium.git/log/chromium?h=118-based
 [2] https://code.qt.io/cgit/qt/qtwebengine-chromium.git/commit/chromium?h=118-based&id=45bdfbd7721749beea9abd18467465e4c9026559
-[3] https://code.qt.io/cgit/qt/qtwebengine-chromium.git/commit/chromium?h=118-based&id=c30894bf867630a8ffcb56c8817c00f3d673f370
+[3] https://code.qt.io/cgit/qt/qtwebengine-chromium.git/commit/chromium?h=118-based&id=eb31082fcba2380e2cc5789aa707328050531e8d
+[4] https://code.qt.io/cgit/qt/qtwebengine-chromium.git/commit/chromium?h=118-based&id=edb5aad8fc938acb291261ec123f5d25f615ddc7
 
 diff --git a/chromium/base/mac/wrap_cg_display.h b/chromium/base/mac/wrap_cg_display.h
 index a579ef1a900..8645627a3a1 100644
@@ -120,6 +122,360 @@ index 0156b748c38..bed248728cc 100644
      // We can't restart the GPU process when running in the host process;
      // instead, just hope for recovery from the context loss.
      return;
+diff --git a/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.cc b/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
+index ec3216d5f92..bb3602f58b9 100644
+--- src/3rdparty/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
++++ src/3rdparty/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.cc
+@@ -54,32 +54,6 @@ using UserAction = FileSystemAccessPermissionContext::UserAction;
+ #endif
+ 
+ namespace {
+-// Returns whether the specified extension receives special handling by the
+-// Windows shell.
+-bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
+-  base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
+-
+-  // .lnk and .scf files may be used to execute arbitrary code (see
+-  // https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
+-  // https://crbug.com/1227995, respectively). '.url' files can be used to read
+-  // arbitrary files (see https://crbug.com/1307930 and
+-  // https://crbug.com/1354518).
+-  if (extension_lower == FILE_PATH_LITERAL("lnk") ||
+-      extension_lower == FILE_PATH_LITERAL("scf") ||
+-      extension_lower == FILE_PATH_LITERAL("url")) {
+-    return true;
+-  }
+-
+-  // Setting a file's extension to a CLSID may conceal its actual file type on
+-  // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
+-  if (!extension_lower.empty() &&
+-      (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
+-      (extension_lower.back() == FILE_PATH_LITERAL('}'))) {
+-    return true;
+-  }
+-  return false;
+-}
+-
+ #if BUILDFLAG(IS_POSIX)
+ base::FilePath ReadSymbolicLink(const base::FilePath& path) {
+   DCHECK(!path.empty());
+@@ -710,80 +684,13 @@ void FileSystemAccessDirectoryHandleImpl::AllEntriesReady(
+       file_system_access_error::Ok(), std::move(entries), has_more_entries);
+ }
+ 
+-// static
+-bool FileSystemAccessDirectoryHandleImpl::IsSafePathComponent(
+-    const std::string& name) {
+-  // This method is similar to net::IsSafePortablePathComponent, with a few
+-  // notable differences where the net version does not consider names safe
+-  // while here we do want to allow them. These cases are:
+-  //  - Names starting with a '.'. These would be hidden files in most file
+-  //    managers, but are something we explicitly want to support for the
+-  //    File System Access API, for names like .git.
+-  //  - Names that end in '.local'. For downloads writing to such files is
+-  //    dangerous since it might modify what code is executed when an executable
+-  //    is ran from the same directory. For the File System Access API this
+-  //    isn't really a problem though, since if a website can write to a .local
+-  //    file via a FileSystemDirectoryHandle they can also just modify the
+-  //    executables in the directory directly.
+-  //
+-  // TODO(https://crbug.com/1154757): Unify this with
+-  // net::IsSafePortablePathComponent, with the result probably ending up in
+-  // base/i18n/file_util_icu.h.
+-
+-  const base::FilePath component = storage::StringToFilePath(name);
+-  // Empty names, or names that contain path separators are invalid.
+-  if (component.empty() || component != component.BaseName() ||
+-      component != component.StripTrailingSeparators()) {
+-    return false;
+-  }
+-
+-  std::u16string component16;
+-#if BUILDFLAG(IS_WIN)
+-  component16.assign(component.value().begin(), component.value().end());
+-#else
+-  std::string component8 = component.AsUTF8Unsafe();
+-  if (!base::UTF8ToUTF16(component8.c_str(), component8.size(), &component16)) {
+-    return false;
+-  }
+-#endif
+-  // base::i18n::IsFilenameLegal blocks names that start with '.', so strip out
+-  // a leading '.' before passing it to that method.
+-  // TODO(mek): Consider making IsFilenameLegal more flexible to support this
+-  // use case.
+-  if (component16[0] == '.') {
+-    component16 = component16.substr(1);
+-  }
+-  if (!base::i18n::IsFilenameLegal(component16)) {
+-    return false;
+-  }
+-
+-  base::FilePath::StringType extension = component.Extension();
+-  if (!extension.empty()) {
+-    extension.erase(extension.begin());  // Erase preceding '.'.
+-  }
+-  if (IsShellIntegratedExtension(extension)) {
+-    return false;
+-  }
+-
+-  if (base::TrimString(component.value(), FILE_PATH_LITERAL("."),
+-                       base::TRIM_TRAILING) != component.value()) {
+-    return false;
+-  }
+-
+-  if (net::IsReservedNameOnWindows(component.value())) {
+-    return false;
+-  }
+-
+-  return true;
+-}
+-
+ blink::mojom::FileSystemAccessErrorPtr
+ FileSystemAccessDirectoryHandleImpl::GetChildURL(
+     const std::string& basename,
+     storage::FileSystemURL* result) {
+   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ 
+-  if (!IsSafePathComponent(basename)) {
++  if (!manager()->IsSafePathComponent(basename)) {
+     return file_system_access_error::FromStatus(
+         FileSystemAccessStatus::kInvalidArgument, "Name is not allowed.");
+   }
+diff --git a/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.h b/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.h
+index 7bbec9a39d9..98452fc1f56 100644
+--- src/3rdparty/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.h
++++ src/3rdparty/chromium/content/browser/file_system_access/file_system_access_directory_handle_impl.h
+@@ -84,14 +84,6 @@ class CONTENT_EXPORT FileSystemAccessDirectoryHandleImpl
+       const std::string& basename,
+       storage::FileSystemURL* result);
+ 
+-  // The File System Access API should not give access to files that might
+-  // trigger special handling from the operating system. This method is used to
+-  // validate that all paths passed to GetFileHandle/GetDirectoryHandle are safe
+-  // to be exposed to the web.
+-  // TODO(https://crbug.com/1154757): Merge this with
+-  // net::IsSafePortablePathComponent.
+-  static bool IsSafePathComponent(const std::string& name);
+-
+  private:
+   // This method creates the file if it does not currently exists. I.e. it is
+   // the implementation for passing create=true to GetFile.
+diff --git a/chromium/content/browser/file_system_access/file_system_access_handle_base.cc b/chromium/content/browser/file_system_access/file_system_access_handle_base.cc
+index 5792ad95e45..44891c0b75c 100644
+--- src/3rdparty/chromium/content/browser/file_system_access/file_system_access_handle_base.cc
++++ src/3rdparty/chromium/content/browser/file_system_access/file_system_access_handle_base.cc
+@@ -217,7 +217,7 @@ void FileSystemAccessHandleBase::DoMove(
+     }
+   }
+ 
+-  if (!FileSystemAccessDirectoryHandleImpl::IsSafePathComponent(
++  if (!manager()->IsSafePathComponent(
+           new_entry_name)) {
+     std::move(callback).Run(file_system_access_error::FromStatus(
+         blink::mojom::FileSystemAccessStatus::kInvalidArgument));
+@@ -250,7 +250,7 @@ void FileSystemAccessHandleBase::DoRename(
+     }
+   }
+ 
+-  if (!FileSystemAccessDirectoryHandleImpl::IsSafePathComponent(
++  if (!manager()->IsSafePathComponent(
+           new_entry_name)) {
+     std::move(callback).Run(file_system_access_error::FromStatus(
+         blink::mojom::FileSystemAccessStatus::kInvalidArgument));
+diff --git a/chromium/content/browser/file_system_access/file_system_access_manager_impl.cc b/chromium/content/browser/file_system_access/file_system_access_manager_impl.cc
+index faa3f12e452..c0d16224f11 100644
+--- src/3rdparty/chromium/content/browser/file_system_access/file_system_access_manager_impl.cc
++++ src/3rdparty/chromium/content/browser/file_system_access/file_system_access_manager_impl.cc
+@@ -15,9 +15,11 @@
+ #include "base/functional/bind.h"
+ #include "base/functional/callback_forward.h"
+ #include "base/functional/callback_helpers.h"
++#include "base/i18n/file_util_icu.h"
+ #include "base/notreached.h"
+ #include "base/ranges/algorithm.h"
+ #include "base/strings/string_util.h"
++#include "base/strings/utf_string_conversions.h"
+ #include "base/task/sequenced_task_runner.h"
+ #include "base/task/task_traits.h"
+ #include "base/task/thread_pool.h"
+@@ -296,6 +298,32 @@ void DidCheckIfDefaultDirectoryExists(
+   }
+ }
+ 
++// Returns whether the specified extension receives special handling by the
++// Windows shell.
++bool IsShellIntegratedExtension(const base::FilePath::StringType& extension) {
++  base::FilePath::StringType extension_lower = base::ToLowerASCII(extension);
++
++  // .lnk and .scf files may be used to execute arbitrary code (see
++  // https://nvd.nist.gov/vuln/detail/CVE-2010-2568 and
++  // https://crbug.com/1227995, respectively). '.url' files can be used to read
++  // arbitrary files (see https://crbug.com/1307930 and
++  // https://crbug.com/1354518).
++  if (extension_lower == FILE_PATH_LITERAL("lnk") ||
++      extension_lower == FILE_PATH_LITERAL("scf") ||
++      extension_lower == FILE_PATH_LITERAL("url")) {
++    return true;
++  }
++
++  // Setting a file's extension to a CLSID may conceal its actual file type on
++  // some Windows versions (see https://nvd.nist.gov/vuln/detail/CVE-2004-0420).
++  if (!extension_lower.empty() &&
++      (extension_lower.front() == FILE_PATH_LITERAL('{')) &&
++      (extension_lower.back() == FILE_PATH_LITERAL('}'))) {
++    return true;
++  }
++  return false;
++}
++
+ }  // namespace
+ 
+ FileSystemAccessManagerImpl::SharedHandleState::SharedHandleState(
+@@ -1749,4 +1777,69 @@ FileSystemAccessManagerImpl::AsWeakPtr() {
+   return weak_factory_.GetWeakPtr();
+ }
+ 
++bool FileSystemAccessManagerImpl::IsSafePathComponent(
++    const std::string& name) {
++  // This method is similar to net::IsSafePortablePathComponent, with a few
++  // notable differences where the net version does not consider names safe
++  // while here we do want to allow them. These cases are:
++  //  - Names starting with a '.'. These would be hidden files in most file
++  //    managers, but are something we explicitly want to support for the
++  //    File System Access API, for names like .git.
++  //  - Names that end in '.local'. For downloads writing to such files is
++  //    dangerous since it might modify what code is executed when an executable
++  //    is ran from the same directory. For the File System Access API this
++  //    isn't really a problem though, since if a website can write to a .local
++  //    file via a FileSystemDirectoryHandle they can also just modify the
++  //
++  // TODO(crbug.com/40159607): Unify this with
++  // net::IsSafePortablePathComponent, with the result probably ending up in
++  // base/i18n/file_util_icu.h.
++
++  const base::FilePath component = storage::StringToFilePath(name);
++  // Empty names, or names that contain path separators are invalid.
++  if (component.empty() || component != component.BaseName() ||
++      component != component.StripTrailingSeparators()) {
++    return false;
++  }
++
++  std::u16string component16;
++#if BUILDFLAG(IS_WIN)
++  component16.assign(component.value().begin(), component.value().end());
++#else
++  std::string component8 = component.AsUTF8Unsafe();
++  if (!base::UTF8ToUTF16(component8.c_str(), component8.size(), &component16)) {
++    return false;
++  }
++#endif
++  // base::i18n::IsFilenameLegal blocks names that start with '.', so strip out
++  // a leading '.' before passing it to that method.
++  // TODO(mek): Consider making IsFilenameLegal more flexible to support this
++  // use case.
++  if (component16[0] == '.') {
++    component16 = component16.substr(1);
++  }
++  if (!base::i18n::IsFilenameLegal(component16)) {
++    return false;
++  }
++
++  base::FilePath::StringType extension = component.Extension();
++  if (!extension.empty()) {
++    extension.erase(extension.begin());  // Erase preceding '.'.
++  }
++  if (IsShellIntegratedExtension(extension)) {
++    return false;
++  }
++
++  if (base::TrimString(component.value(), FILE_PATH_LITERAL("."),
++                       base::TRIM_TRAILING) != component.value()) {
++    return false;
++  }
++
++  if (net::IsReservedNameOnWindows(component.value())) {
++    return false;
++  }
++
++  return true;
++}
++
+ }  // namespace content
+diff --git a/chromium/content/browser/file_system_access/file_system_access_manager_impl.h b/chromium/content/browser/file_system_access/file_system_access_manager_impl.h
+index 2b6828054b7..eeda10526b8 100644
+--- src/3rdparty/chromium/content/browser/file_system_access/file_system_access_manager_impl.h
++++ src/3rdparty/chromium/content/browser/file_system_access/file_system_access_manager_impl.h
+@@ -359,6 +359,14 @@ class CONTENT_EXPORT FileSystemAccessManagerImpl
+ 
+   void Shutdown();
+ 
++  // The File System Access API should not give access to files that might
++  // trigger special handling from the operating system. This method is used to
++  // validate that all paths passed to GetFileHandle/GetDirectoryHandle are safe
++  // to be exposed to the web.
++  // TODO(crbug.com/40159607): Merge this with
++  // net::IsSafePortablePathComponent.
++  bool IsSafePathComponent(const std::string& name);
++
+   // Invokes `method` on the correct sequence on the FileSystemOperationRunner,
+   // passing `args` and a callback to the method.
+   // The passed in `callback` is wrapped to make sure it is called on the
+diff --git a/chromium/content/browser/renderer_host/cross_process_frame_connector.cc b/chromium/content/browser/renderer_host/cross_process_frame_connector.cc
+index 00eb0fb1348..2944d939029 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/cross_process_frame_connector.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/cross_process_frame_connector.cc
+@@ -60,10 +60,11 @@ CrossProcessFrameConnector::~CrossProcessFrameConnector() {
+   }
+ 
+   // Notify the view of this object being destroyed, if the view still exists.
+-  SetView(nullptr);
++  SetView(nullptr, /*allow_paint_holding=*/false);
+ }
+ 
+-void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
++void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view,
++                                         bool allow_paint_holding) {
+   // Detach ourselves from the previous |view_|.
+   if (view_) {
+     RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView();
+@@ -110,7 +111,7 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
+     if (frame_proxy_in_parent_renderer_ &&
+         frame_proxy_in_parent_renderer_->is_render_frame_proxy_live()) {
+       frame_proxy_in_parent_renderer_->GetAssociatedRemoteFrame()
+-          ->SetFrameSinkId(view_->GetFrameSinkId());
++          ->SetFrameSinkId(view_->GetFrameSinkId(), allow_paint_holding);
+     }
+   }
+ }
+diff --git a/chromium/content/browser/renderer_host/cross_process_frame_connector.h b/chromium/content/browser/renderer_host/cross_process_frame_connector.h
+index 05ecb60aebe..4436cd1fba7 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/cross_process_frame_connector.h
++++ src/3rdparty/chromium/content/browser/renderer_host/cross_process_frame_connector.h
+@@ -100,7 +100,7 @@ class CONTENT_EXPORT CrossProcessFrameConnector {
+   // above.
+   RenderWidgetHostViewChildFrame* get_view_for_testing() { return view_; }
+ 
+-  void SetView(RenderWidgetHostViewChildFrame* view);
++  void SetView(RenderWidgetHostViewChildFrame* view, bool allow_paint_holding);
+ 
+   // Returns the parent RenderWidgetHostView or nullptr if it doesn't have one.
+   virtual RenderWidgetHostViewBase* GetParentRenderWidgetHostView();
+diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.cc b/chromium/content/browser/renderer_host/delegated_frame_host.cc
+index 3ea56e0e536..499a23b5209 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/delegated_frame_host.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/delegated_frame_host.cc
+@@ -503,7 +503,10 @@ void DelegatedFrameHost::ContinueDelegatedFrameEviction(
+   // preventing the FrameTree from being traversed. This could happen during
+   // navigation involving BFCache. This should not occur with
+   // features::kEvictSubtree.
+-  DCHECK(!surface_ids.empty() ||
++  // We do allow the surface ids to be empty if we
++  // don't have a local surface id, since that means we don't have memory
++  // allocated in viz.
++  DCHECK(!surface_ids.empty() || !local_surface_id_.is_valid() ||
+          !base::FeatureList::IsEnabled(features::kEvictSubtree));
+   if (!surface_ids.empty()) {
+     DCHECK(host_frame_sink_manager_);
 diff --git a/chromium/content/browser/renderer_host/navigation_controller_impl.cc b/chromium/content/browser/renderer_host/navigation_controller_impl.cc
 index db818eb83e9..084fd00eeae 100644
 --- src/3rdparty/chromium/content/browser/renderer_host/navigation_controller_impl.cc
@@ -167,6 +523,524 @@ index ba9be480a81..987963d4bf4 100644
                                                const GURL& url);
  
    // Adds details from a committed navigation to `entry` and the
+diff --git a/chromium/content/browser/renderer_host/navigator.cc b/chromium/content/browser/renderer_host/navigator.cc
+index e4cdb82d559..fd5e2eb26c3 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/navigator.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/navigator.cc
+@@ -32,6 +32,7 @@
+ #include "content/browser/web_package/prefetched_signed_exchange_cache.h"
+ #include "content/browser/webui/web_ui_controller_factory_registry.h"
+ #include "content/browser/webui/web_ui_impl.h"
++#include "content/common/features.h"
+ #include "content/common/navigation_params_utils.h"
+ #include "content/public/browser/browser_context.h"
+ #include "content/public/browser/content_browser_client.h"
+@@ -516,17 +517,56 @@ void Navigator::DidNavigate(
+   // Store this information before DidNavigateFrame() potentially swaps RFHs.
+   url::Origin old_frame_origin = old_frame_host->GetLastCommittedOrigin();
+ 
++  // RenderFrameHostImpl::DidNavigate will update the url, and may cause the
++  // node to consider itself no longer on the initial empty document. Record
++  // whether we're leaving the initial empty document before that.
++  bool was_on_initial_empty_document =
++      frame_tree_node->is_on_initial_empty_document();
++
++  // Allow main frame paint holding in the following cases:
++  //  - We don't have an animated transition. See crbug.com/360844863.
++  //  - At least one of the following conditions is true:
++  //    - This is a navigation from the initial document. This part helps with
++  //      tests. See crbug.com/367623929.
++  //    - This is a same origin navigation (or we're not limiting cross-origin
++  //      paint holding)
++  //    - There is a user activation. This means that the user interacted with
++  //      the page. Commonly used attacks are done without user activation --
++  //      which will not enable paint holding. However, if the user interacts
++  //      with the page, we treat it as a valid case for paint holding.
++  //    - The client allows non-activated cross origin paintholding, which is
++  //      currently the case with webview.
++  //
++  // See https://issues.chromium.org/40942531 for reasons we limit paint
++  // holding.
++  ContentBrowserClient* client = GetContentClient()->browser();
++  const bool allow_main_frame_paint_holding =
++      (was_on_initial_empty_document ||
++       old_frame_origin.IsSameOriginWith(params.origin) ||
++       old_frame_host->HasStickyUserActivation() ||
++       client->AllowNonActivatedCrossOriginPaintHolding() ||
++       !base::FeatureList::IsEnabled(
++           kLimitCrossOriginNonActivatedPaintHolding));
++
++  // Only allow subframe paint holding for same origin.
++  const bool allow_subframe_paint_holding =
++      old_frame_origin.IsSameOriginWith(params.origin);
++
+   // DidNavigateFrame() must be called before replicating the new origin and
+   // other properties to proxies.  This is because it destroys the subframes of
+   // the frame we're navigating from, which might trigger those subframes to
+   // run unload handlers.  Those unload handlers should still see the old
+   // frame's origin.  See https://crbug.com/825283.
++  const bool allow_paint_holding = frame_tree_node->IsMainFrame()
++                                       ? allow_main_frame_paint_holding
++                                       : allow_subframe_paint_holding;
++
+   frame_tree_node->render_manager()->DidNavigateFrame(
+       render_frame_host, navigation_request->common_params().has_user_gesture,
+       was_within_same_document,
+       navigation_request->browsing_context_group_swap()
+           .ShouldClearProxiesOnCommit(),
+-      navigation_request->commit_params().frame_policy);
++      navigation_request->commit_params().frame_policy, allow_paint_holding);
+ 
+   // The main frame, same site, and cross-site navigation checks for user
+   // activation mirror the checks in DocumentLoader::CommitNavigation() (note:
+@@ -593,12 +633,6 @@ void Navigator::DidNavigate(
+     render_frame_host->GetPage().SetContentsMimeType(params.contents_mime_type);
+   }
+ 
+-  // RenderFrameHostImpl::DidNavigate will update the url, and may cause the
+-  // node to consider itself no longer on the initial empty document. Record
+-  // whether we're leaving the initial empty document before that.
+-  bool was_on_initial_empty_document =
+-      frame_tree_node->is_on_initial_empty_document();
+-
+   render_frame_host->DidNavigate(params, navigation_request.get(),
+                                  was_within_same_document);
+ 
+diff --git a/chromium/content/browser/renderer_host/render_frame_host_impl.cc b/chromium/content/browser/renderer_host/render_frame_host_impl.cc
+index d1d0efb398b..a45f586a3c4 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_impl.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_impl.cc
+@@ -8546,7 +8546,8 @@ void RenderFrameHostImpl::AdoptPortal(
+                                        ->render_manager()
+                                        ->GetRenderWidgetHostView()
+                                        ->GetFrameSinkId();
+-  proxy_host->GetAssociatedRemoteFrame()->SetFrameSinkId(frame_sink_id);
++  // generally disallow paint holding for security reasons
++  proxy_host->GetAssociatedRemoteFrame()->SetFrameSinkId(frame_sink_id, /*allow_paint_holding*/ false);
+ 
+   std::move(callback).Run(
+       proxy_host->frame_tree_node()->current_replication_state().Clone(),
+diff --git a/chromium/content/browser/renderer_host/render_frame_host_manager.cc b/chromium/content/browser/renderer_host/render_frame_host_manager.cc
+index 9f5cddd99a0..91114140ea4 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_manager.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_manager.cc
+@@ -731,10 +731,11 @@ void RenderFrameHostManager::DidNavigateFrame(
+     bool was_caused_by_user_gesture,
+     bool is_same_document_navigation,
+     bool clear_proxies_on_commit,
+-    const blink::FramePolicy& frame_policy) {
++    const blink::FramePolicy& frame_policy,
++    bool allow_paint_holding) {
+   CommitPendingIfNecessary(render_frame_host, was_caused_by_user_gesture,
+-                           is_same_document_navigation,
+-                           clear_proxies_on_commit);
++                           is_same_document_navigation, clear_proxies_on_commit,
++                           allow_paint_holding);
+ 
+   // Make sure any dynamic changes to this frame's sandbox flags and permissions
+   // policy that were made prior to navigation take effect.  This should only
+@@ -770,7 +771,8 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
+     RenderFrameHostImpl* render_frame_host,
+     bool was_caused_by_user_gesture,
+     bool is_same_document_navigation,
+-    bool clear_proxies_on_commit) {
++    bool clear_proxies_on_commit,
++    bool allow_paint_holding) {
+   if (!speculative_render_frame_host_) {
+     // There's no speculative RenderFrameHost so it must be that the current
+     // RenderFrameHost completed a navigation.
+@@ -784,7 +786,8 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
+   if (render_frame_host == speculative_render_frame_host_.get()) {
+     // A cross-RenderFrameHost navigation completed, so show the new renderer.
+     CommitPending(std::move(speculative_render_frame_host_),
+-                  std::move(stored_page_to_restore_), clear_proxies_on_commit);
++                  std::move(stored_page_to_restore_), clear_proxies_on_commit,
++                  allow_paint_holding);
+ 
+     if (GetNavigationQueueingFeatureLevel() >=
+         NavigationQueueingFeatureLevel::kAvoidRedundantCancellations) {
+@@ -841,9 +844,26 @@ void RenderFrameHostManager::CommitPendingIfNecessary(
+     // output on prerender activation.
+     if (render_frame_host_->lifecycle_state() !=
+         LifecycleStateImpl::kPrerendering) {
+-      static_cast<RenderWidgetHostImpl*>(
+-          render_frame_host_->GetView()->GetRenderWidgetHost())
+-          ->StartNewContentRenderingTimeout();
++      auto* rwhi = static_cast<RenderWidgetHostImpl*>(
++          render_frame_host_->GetView()->GetRenderWidgetHost());
++
++      rwhi->StartNewContentRenderingTimeout();
++      // Force the timer to expire immediately if we don't allow main frame
++      // paint holding.
++      if (frame_tree_node_->IsMainFrame() && !allow_paint_holding) {
++        // We post task here, since this evicts a surface but the embedding of a
++        // new surface would be done in the same stack as this call. The
++        // ordering of whether the new surface has or has not yet been embedded
++        // differs for different platforms, and we always want the new surface
++        // to be embedded before we evict. Hence, we post a task. In practice
++        // this still disables paint holding unless this task is delayed for a
++        // long time.
++        GetUIThreadTaskRunner({})->PostTask(
++            FROM_HERE,
++            base::BindOnce(
++                &RenderWidgetHostImpl::ForceFirstFrameAfterNavigationTimeout,
++                rwhi->GetWeakPtr()));
++      }
+     }
+   }
+ 
+@@ -1467,7 +1487,8 @@ void RenderFrameHostManager::PerformEarlyRenderFrameHostSwapIfNeeded(
+ 
+   CommitPending(
+       std::move(speculative_render_frame_host_), nullptr,
+-      request->browsing_context_group_swap().ShouldClearProxiesOnCommit());
++      request->browsing_context_group_swap().ShouldClearProxiesOnCommit(),
++      /* allow_paint_holding */ false);
+   request->SetAssociatedRFHType(
+       NavigationRequest::AssociatedRenderFrameHostType::CURRENT);
+ 
+@@ -4028,7 +4049,8 @@ void RenderFrameHostManager::SetRWHViewForInnerFrameTree(
+     RenderWidgetHostViewChildFrame* child_rwhv) {
+   DCHECK(IsMainFrameForInnerDelegate());
+   DCHECK(GetProxyToOuterDelegate());
+-  GetProxyToOuterDelegate()->SetChildRWHView(child_rwhv, nullptr);
++  GetProxyToOuterDelegate()->SetChildRWHView(child_rwhv, nullptr,
++                                             /*allow_paint_holding=*/false);
+ }
+ 
+ bool RenderFrameHostManager::InitRenderView(
+@@ -4340,7 +4362,8 @@ RenderFrameHostManager::GetFrameTokenForSiteInstanceGroup(
+ void RenderFrameHostManager::CommitPending(
+     std::unique_ptr<RenderFrameHostImpl> pending_rfh,
+     std::unique_ptr<StoredPage> pending_stored_page,
+-    bool clear_proxies_on_commit) {
++    bool clear_proxies_on_commit,
++    bool allow_paint_holding) {
+   TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
+                "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
+   CHECK(pending_rfh);
+@@ -4593,9 +4616,10 @@ void RenderFrameHostManager::CommitPending(
+   // valid surface id, because it already has that surface embedded through
+   // `RenderFrameHostImpl::WillLeaveBackForwardCache` and the timeout that
+   // would be set here will clear that frame (incorrectly).
+-  if (is_main_frame && old_view && old_view != new_view) {
+-    // We should take the fallback if we're not coming from BFCache or if we
+-    // don't have a valid surface id to display.
++  if (is_main_frame && allow_paint_holding && old_view && old_view != new_view) {
++    // If allowed, we should take the fallback in any of the following cases:
++    //  - We're not coming from BFCache
++    //  - We don't have a valid surface id to display.
+     auto* render_widget_host_view_base =
+         static_cast<RenderWidgetHostViewBase*>(render_frame_host_->GetView());
+     should_take_fallback_content =
+@@ -4730,7 +4754,7 @@ void RenderFrameHostManager::CommitPending(
+   if (proxy_to_parent_or_outer_delegate) {
+     proxy_to_parent_or_outer_delegate->SetChildRWHView(
+         static_cast<RenderWidgetHostViewChildFrame*>(new_view),
+-        old_size ? &*old_size : nullptr);
++        old_size ? &*old_size : nullptr, allow_paint_holding);
+   }
+ 
+   if (render_frame_host_->is_local_root()) {
+@@ -5136,8 +5160,10 @@ void RenderFrameHostManager::CreateNewFrameForInnerDelegateAttachIfNecessary() {
+   // Swap in the speculative frame. It will later be replaced when
+   // WebContents::AttachToOuterWebContentsFrame is called.
+   speculative_render_frame_host_->SwapIn();
++
+   CommitPending(std::move(speculative_render_frame_host_), nullptr,
+-                false /* clear_proxies_on_commit */);
++                false /* clear_proxies_on_commit */,
++                /* allow_paint_holding */ false);
+   NotifyPrepareForInnerDelegateAttachComplete(true /* success */);
+ }
+ 
+diff --git a/chromium/content/browser/renderer_host/render_frame_host_manager.h b/chromium/content/browser/renderer_host/render_frame_host_manager.h
+index 9257b8c5f93..46acf6a9380 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_manager.h
++++ src/3rdparty/chromium/content/browser/renderer_host/render_frame_host_manager.h
+@@ -322,7 +322,8 @@ class CONTENT_EXPORT RenderFrameHostManager {
+                         bool was_caused_by_user_gesture,
+                         bool is_same_document_navigation,
+                         bool clear_proxies_on_commit,
+-                        const blink::FramePolicy& frame_policy);
++                        const blink::FramePolicy& frame_policy,
++                        bool allow_paint_holding);
+ 
+   // Called when this frame's opener is changed to the frame specified by
+   // |opener_frame_token| in |source_site_instance_group|'s process.  This
+@@ -971,15 +972,18 @@ class CONTENT_EXPORT RenderFrameHostManager {
+   // |clear_proxies_on_commit| Indicates if the proxies and opener must be
+   // removed during the commit. This can happen following some BrowsingInstance
+   // swaps, such as those for COOP.
++  // |allow_paint_holding| Indicates whether paint holding is allowed.
+   void CommitPending(std::unique_ptr<RenderFrameHostImpl> pending_rfh,
+                      std::unique_ptr<StoredPage> pending_stored_page,
+-                     bool clear_proxies_on_commit);
++                     bool clear_proxies_on_commit,
++                     bool allow_paint_holding);
+ 
+   // Helper to call CommitPending() in all necessary cases.
+   void CommitPendingIfNecessary(RenderFrameHostImpl* render_frame_host,
+                                 bool was_caused_by_user_gesture,
+                                 bool is_same_document_navigation,
+-                                bool clear_proxies_on_commit);
++                                bool clear_proxies_on_commit,
++                                bool allow_paint_holding);
+ 
+   // Runs the unload handler in the old RenderFrameHost, after the new
+   // RenderFrameHost has committed.  |old_render_frame_host| will either be
+diff --git a/chromium/content/browser/renderer_host/render_frame_proxy_host.cc b/chromium/content/browser/renderer_host/render_frame_proxy_host.cc
+index 2ac59af2958..6ac750e7155 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_frame_proxy_host.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/render_frame_proxy_host.cc
+@@ -192,10 +192,10 @@ RenderFrameProxyHost::~RenderFrameProxyHost() {
+   TRACE_EVENT_END("navigation", perfetto::Track::FromPointer(this));
+ }
+ 
+-void RenderFrameProxyHost::SetChildRWHView(
+-    RenderWidgetHostViewChildFrame* view,
+-    const gfx::Size* initial_frame_size) {
+-  cross_process_frame_connector_->SetView(view);
++void RenderFrameProxyHost::SetChildRWHView(RenderWidgetHostViewChildFrame* view,
++                                           const gfx::Size* initial_frame_size,
++                                           bool allow_paint_holding) {
++  cross_process_frame_connector_->SetView(view, allow_paint_holding);
+   if (initial_frame_size)
+     cross_process_frame_connector_->SetLocalFrameSize(*initial_frame_size);
+ }
+diff --git a/chromium/content/browser/renderer_host/render_frame_proxy_host.h b/chromium/content/browser/renderer_host/render_frame_proxy_host.h
+index 08c1d72af90..c63589a7c31 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_frame_proxy_host.h
++++ src/3rdparty/chromium/content/browser/renderer_host/render_frame_proxy_host.h
+@@ -164,7 +164,8 @@ class CONTENT_EXPORT RenderFrameProxyHost
+   // receives its size from the parent via FrameHostMsg_UpdateResizeParams
+   // before it begins parsing the content.
+   void SetChildRWHView(RenderWidgetHostViewChildFrame* view,
+-                       const gfx::Size* initial_frame_size);
++                       const gfx::Size* initial_frame_size,
++                       bool allow_paint_holding);
+ 
+   RenderViewHostImpl* GetRenderViewHost();
+ 
+diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+index f27648e12c1..a337dd6a96b 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_widget_host_impl.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+@@ -117,6 +117,7 @@
+ #include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
+ #include "third_party/blink/public/common/storage_key/storage_key.h"
+ #include "third_party/blink/public/common/web_preferences/web_preferences.h"
++#include "third_party/blink/public/common/widget/constants.h"
+ #include "third_party/blink/public/common/widget/visual_properties.h"
+ #include "third_party/blink/public/mojom/drag/drag.mojom.h"
+ #include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom.h"
+@@ -165,10 +166,6 @@ using blink::WebMouseWheelEvent;
+ namespace content {
+ namespace {
+ 
+-// How long to wait for newly loaded content to send a compositor frame
+-// before clearing previously displayed graphics.
+-constexpr base::TimeDelta kNewContentRenderingDelay = base::Seconds(4);
+-
+ constexpr gfx::Rect kInvalidScreenRect(std::numeric_limits<int>::max(),
+                                        std::numeric_limits<int>::max(),
+                                        0,
+@@ -438,7 +435,7 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(
+               switches::kDisableHangMonitor)),
+       latency_tracker_(delegate_),
+       hung_renderer_delay_(kHungRendererDelay),
+-      new_content_rendering_delay_(kNewContentRenderingDelay),
++      new_content_rendering_delay_(blink::kNewContentRenderingDelay),
+       frame_token_message_queue_(std::move(frame_token_message_queue)),
+       render_frame_metadata_provider_(
+ #if BUILDFLAG(IS_MAC)
+diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+index b190c86708d..632973c779e 100644
+--- src/3rdparty/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
++++ src/3rdparty/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+@@ -406,7 +406,7 @@ void RenderWidgetHostViewChildFrame::Destroy() {
+   // have already been cleared when RenderWidgetHostViewBase notified its
+   // observers of our impending destruction.
+   if (frame_connector_) {
+-    frame_connector_->SetView(nullptr);
++    frame_connector_->SetView(nullptr, /*allow_paint_holding=*/false);
+     SetFrameConnector(nullptr);
+   }
+ 
+diff --git a/chromium/content/common/features.cc b/chromium/content/common/features.cc
+index 52443a0118c..e80454c2edd 100644
+--- src/3rdparty/chromium/content/common/features.cc
++++ src/3rdparty/chromium/content/common/features.cc
+@@ -59,6 +59,11 @@ BASE_FEATURE(kWindowOpenFileSelectFix,
+              "WindowOpenFileSelectFix",
+              base::FEATURE_ENABLED_BY_DEFAULT);
+ 
++// Flag guard for fix for crbug.com/40942531.
++BASE_FEATURE(kLimitCrossOriginNonActivatedPaintHolding,
++             "LimitCrossOriginNonActivatedPaintHolding",
++             base::FEATURE_ENABLED_BY_DEFAULT);
++
+ // Please keep features in alphabetical order.
+ 
+ }  // namespace content
+diff --git a/chromium/content/common/features.h b/chromium/content/common/features.h
+index 5b5feb19663..92d7b515f86 100644
+--- src/3rdparty/chromium/content/common/features.h
++++ src/3rdparty/chromium/content/common/features.h
+@@ -72,6 +72,8 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kSpeculativeServiceWorkerStartup);
+ // Flag guard for fix for crbug.com/1414936.
+ CONTENT_EXPORT BASE_DECLARE_FEATURE(kWindowOpenFileSelectFix);
+ 
++CONTENT_EXPORT BASE_DECLARE_FEATURE(kLimitCrossOriginNonActivatedPaintHolding);
++
+ // Please keep features in alphabetical order.
+ 
+ }  // namespace content
+diff --git a/chromium/content/public/browser/content_browser_client.cc b/chromium/content/public/browser/content_browser_client.cc
+index f30e5094533..59d3cc16e25 100644
+--- src/3rdparty/chromium/content/public/browser/content_browser_client.cc
++++ src/3rdparty/chromium/content/public/browser/content_browser_client.cc
+@@ -1593,4 +1593,8 @@ bool ContentBrowserClient::
+   return true;
+ }
+ 
++bool ContentBrowserClient::AllowNonActivatedCrossOriginPaintHolding() {
++  return false;
++}
++
+ }  // namespace content
+diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h
+index 3ae26ba017f..ded95892ab6 100644
+--- src/3rdparty/chromium/content/public/browser/content_browser_client.h
++++ src/3rdparty/chromium/content/public/browser/content_browser_client.h
+@@ -2619,6 +2619,10 @@ class CONTENT_EXPORT ContentBrowserClient {
+   // "Cache-control: no-store" header in BFCache.
+   virtual bool ShouldAllowBackForwardCacheForCacheControlNoStorePage(
+       content::BrowserContext* browser_context);
++
++  // Indicates whether this client allows paint holding in cross-origin
++  // navigations even if there was no user activation.
++  virtual bool AllowNonActivatedCrossOriginPaintHolding();
+ };
+ 
+ }  // namespace content
+diff --git a/chromium/content/renderer/media/media_factory.cc b/chromium/content/renderer/media/media_factory.cc
+index a6859aa3532..3316f1aaedc 100644
+--- src/3rdparty/chromium/content/renderer/media/media_factory.cc
++++ src/3rdparty/chromium/content/renderer/media/media_factory.cc
+@@ -690,7 +690,7 @@ MediaFactory::CreateRendererFactorySelector(
+ 
+     media::ObserveOverlayStateCB observe_overlay_state_cb =
+         base::BindRepeating(&OverlayStateObserverImpl::Create,
+-                            render_thread->GetOverlayStateServiceProvider());
++                            base::RetainedRef(render_thread->GetOverlayStateServiceProvider()));
+ 
+     factory_selector->AddFactory(
+         RendererType::kMediaFoundation,
+diff --git a/chromium/content/renderer/media/win/overlay_state_observer_impl.cc b/chromium/content/renderer/media/win/overlay_state_observer_impl.cc
+index 7cb6729a1e2..1de0ddc46ab 100644
+--- src/3rdparty/chromium/content/renderer/media/win/overlay_state_observer_impl.cc
++++ src/3rdparty/chromium/content/renderer/media/win/overlay_state_observer_impl.cc
+@@ -16,7 +16,7 @@ OverlayStateObserverImpl::Create(
+     StateChangedCB state_changed_cb) {
+   if (overlay_state_service_provider) {
+     return base::WrapUnique(new OverlayStateObserverImpl(
+-        overlay_state_service_provider, mailbox, state_changed_cb));
++        overlay_state_service_provider, mailbox, std::move(state_changed_cb)));
+   }
+   return nullptr;
+ }
+diff --git a/chromium/content/renderer/media/win/overlay_state_service_provider.h b/chromium/content/renderer/media/win/overlay_state_service_provider.h
+index a1b97b4429f..491a44ba2ea 100644
+--- src/3rdparty/chromium/content/renderer/media/win/overlay_state_service_provider.h
++++ src/3rdparty/chromium/content/renderer/media/win/overlay_state_service_provider.h
+@@ -15,11 +15,19 @@ class GpuChannelHost;
+ 
+ namespace content {
+ 
+-class OverlayStateServiceProvider {
++class OverlayStateServiceProvider
++    : public base::RefCountedThreadSafe<OverlayStateServiceProvider> {
+  public:
+   virtual bool RegisterObserver(
+       mojo::PendingRemote<gpu::mojom::OverlayStateObserver> pending_remote,
+       const gpu::Mailbox& mailbox) = 0;
++
++ protected:
++  friend class base::RefCountedThreadSafe<OverlayStateServiceProvider>;
++  OverlayStateServiceProvider() = default;
++  OverlayStateServiceProvider(const OverlayStateServiceProvider&) = delete;
++  OverlayStateServiceProvider& operator=(const OverlayStateServiceProvider&) =
++      delete;
+   virtual ~OverlayStateServiceProvider() = default;
+ };
+ 
+@@ -29,7 +37,6 @@ class OverlayStateServiceProviderImpl : public OverlayStateServiceProvider {
+  public:
+   explicit OverlayStateServiceProviderImpl(
+       scoped_refptr<gpu::GpuChannelHost> channel);
+-  ~OverlayStateServiceProviderImpl() override;
+ 
+   bool RegisterObserver(
+       mojo::PendingRemote<gpu::mojom::OverlayStateObserver> pending_remote,
+@@ -43,6 +50,7 @@ class OverlayStateServiceProviderImpl : public OverlayStateServiceProvider {
+       delete;
+   OverlayStateServiceProviderImpl& operator=(
+       const OverlayStateServiceProviderImpl&) = delete;
++  ~OverlayStateServiceProviderImpl() override;
+ 
+   scoped_refptr<gpu::GpuChannelHost> channel_;
+ };
+diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc
+index 328ed025f6b..f44428ecb13 100644
+--- src/3rdparty/chromium/content/renderer/render_thread_impl.cc
++++ src/3rdparty/chromium/content/renderer/render_thread_impl.cc
+@@ -1268,7 +1268,7 @@ scoped_refptr<DCOMPTextureFactory> RenderThreadImpl::GetDCOMPTextureFactory() {
+   return dcomp_texture_factory_;
+ }
+ 
+-OverlayStateServiceProvider*
++scoped_refptr<OverlayStateServiceProvider>
+ RenderThreadImpl::GetOverlayStateServiceProvider() {
+   DCHECK(IsMainThread());
+   // Only set 'overlay_state_service_provider_' if Media Foundation for clear
+@@ -1282,11 +1282,12 @@ RenderThreadImpl::GetOverlayStateServiceProvider() {
+         return nullptr;
+       }
+       overlay_state_service_provider_ =
+-          std::make_unique<OverlayStateServiceProviderImpl>(std::move(channel));
++          base::MakeRefCounted<OverlayStateServiceProviderImpl>(
++              std::move(channel));
+     }
+   }
+ 
+-  return overlay_state_service_provider_.get();
++  return overlay_state_service_provider_;
+ }
+ #endif  // BUILDFLAG(IS_WIN)
+ 
+diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h
+index 0d91d61008a..1e3a986f9e7 100644
+--- src/3rdparty/chromium/content/renderer/render_thread_impl.h
++++ src/3rdparty/chromium/content/renderer/render_thread_impl.h
+@@ -265,7 +265,7 @@ class CONTENT_EXPORT RenderThreadImpl
+   // The OverlayStateService is only available where Media Foundation for
+   // clear is supported, otherwise GetOverlayStateServiceProvider will return
+   // nullptr.
+-  OverlayStateServiceProvider* GetOverlayStateServiceProvider();
++  scoped_refptr<OverlayStateServiceProvider> GetOverlayStateServiceProvider();
+ #endif
+ 
+   blink::WebVideoCaptureImplManager* video_capture_impl_manager() const {
+@@ -530,7 +530,7 @@ class CONTENT_EXPORT RenderThreadImpl
+ 
+ #if BUILDFLAG(IS_WIN)
+   scoped_refptr<DCOMPTextureFactory> dcomp_texture_factory_;
+-  std::unique_ptr<OverlayStateServiceProviderImpl>
++  scoped_refptr<OverlayStateServiceProviderImpl>
+       overlay_state_service_provider_;
+ #endif
+ 
 diff --git a/chromium/gpu/config/software_rendering_list.json b/chromium/gpu/config/software_rendering_list.json
 index a2f6aa5f2cf..0878fb2599e 100644
 --- src/3rdparty/chromium/gpu/config/software_rendering_list.json
@@ -195,6 +1069,56 @@ index a2f6aa5f2cf..0878fb2599e 100644
      {
        "id": 159,
        "cr_bugs": [902247],
+diff --git a/chromium/third_party/blink/common/widget/constants.cc b/chromium/third_party/blink/common/widget/constants.cc
+index 212050c1221..2b27ca8d7e9 100644
+--- src/3rdparty/chromium/third_party/blink/common/widget/constants.cc
++++ src/3rdparty/chromium/third_party/blink/common/widget/constants.cc
+@@ -8,4 +8,6 @@ namespace blink {
+ 
+ const int kMinimumWindowSize = 100;
+ 
++const base::TimeDelta kNewContentRenderingDelay = base::Seconds(4);
++
+ }  // namespace blink
+diff --git a/chromium/third_party/blink/public/common/widget/constants.h b/chromium/third_party/blink/public/common/widget/constants.h
+index 95749573237..69aedfbc137 100644
+--- src/3rdparty/chromium/third_party/blink/public/common/widget/constants.h
++++ src/3rdparty/chromium/third_party/blink/public/common/widget/constants.h
+@@ -5,6 +5,7 @@
+ #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_WIDGET_CONSTANTS_H_
+ #define THIRD_PARTY_BLINK_PUBLIC_COMMON_WIDGET_CONSTANTS_H_
+ 
++#include "base/time/time.h"
+ #include "third_party/blink/public/common/common_export.h"
+ 
+ namespace blink {
+@@ -13,6 +14,9 @@ namespace blink {
+ // window object
+ BLINK_COMMON_EXPORT extern const int kMinimumWindowSize;
+ 
++// The timeout for clearing old paint for a cross-document navigation.
++BLINK_COMMON_EXPORT extern const base::TimeDelta kNewContentRenderingDelay;
++
+ }  // namespace blink
+ 
+ #endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_WIDGET_CONSTANTS_H_
+diff --git a/chromium/third_party/blink/public/mojom/frame/remote_frame.mojom b/chromium/third_party/blink/public/mojom/frame/remote_frame.mojom
+index 4d891d46b67..e3c22c2059b 100644
+--- src/3rdparty/chromium/third_party/blink/public/mojom/frame/remote_frame.mojom
++++ src/3rdparty/chromium/third_party/blink/public/mojom/frame/remote_frame.mojom
+@@ -404,7 +404,11 @@ interface RemoteFrame {
+ 
+   // Notifies this remote frame that its associated compositing
+   // destination (RenderWidgetHostView) has changed.
+-  SetFrameSinkId(viz.mojom.FrameSinkId frame_sink_id);
++  //
*** 1041 LINES SKIPPED ***