CVE-2026-13861
Overview
Files Changed
content/browser/renderer_host/render_process_host_impl.cccontent/browser/renderer_host/render_process_host_impl.h
Patch
From be42acc9b0c4c79c9ee7cb849bc7dabdfbb3d535 Mon Sep 17 00:00:00 2001 From: Charlie Reis <[email protected]> Date: Sun, 31 May 2026 22:48:39 -0700 Subject: [PATCH] Convert RenderProcessHostImpl::browser_context_ to MiraclePtr. Bug: 495456765 Change-Id: Ib31a537b009ae9e73b297a21483834704c2bf73b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7885218 Commit-Queue: Keishi Hattori <[email protected]> Auto-Submit: Charlie Reis <[email protected]> Reviewed-by: Keishi Hattori <[email protected]> Cr-Commit-Position: refs/heads/main@{#1639175} --- diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 5d5ef2bd..32934ca3 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -2728,7 +2728,7 @@ const { proto->set_id(GetDeprecatedID()); proto->set_process_lock(GetProcessLock().ToString()); - proto.Set(TraceProto::kBrowserContext, browser_context_); + proto.Set(TraceProto::kBrowserContext, browser_context_.get()); // Pid() can be called only on valid process, so we should check for this // before accessing it. In addition, Pid() should only be read once the diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 5618ad6d3..9229f4aa 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h @@ -1431,10 +1431,8 @@ // The globally-unique identifier for this RenderProcessHost. const ChildProcessId id_; - // This field is not a raw_ptr<> because problems related to passing to a - // templated && parameter, which is later forwarded to something that doesn't - // vibe with raw_ptr<T>. - RAW_PTR_EXCLUSION BrowserContext* browser_context_ = nullptr; + // The BrowserContext this RenderProcessHost exists within. + raw_ptr<BrowserContext> browser_context_ = nullptr; // Owned by `browser_context_`. raw_ptr<StoragePartitionImpl> storage_partition_impl_;
Original Bug Report
Potential UAF in RenderProcessHostImpl::BindVideoDecodePerfHistory
Flapjack (go/flapjack), an LLM-powered static analysis tool, has identified the following potential security issue.
Overview: A potential Use-After-Free vulnerability exists in RenderProcessHostImpl due to a dangling BrowserContext pointer. If an attacker can keep the host alive past the context’s destruction, calling BindVideoDecodePerfHistory dereferences the freed memory. This allows a compromised renderer to achieve a sandbox escape by hijacking virtual method calls.
Affected files:
content/browser/renderer_host/render_process_host_impl.cccontent/browser/renderer_host/render_process_host_impl.h
Estimated timestamp from git blame: 2024-04-24
Conclusion: A potential Use-After-Free in RenderProcessHostImpl::BindVideoDecodePerfHistory allows a compromised renderer to achieve a Sandbox Escape in the browser process.
Initial logic and parameters regarding RenderProcessHostImpl lifetime and BrowserContext destruction are validated. The browser_context_ pointer is explicitly marked with RAW_PTR_EXCLUSION, bypassing MiraclePtr protections. If a listener (e.g., RenderFrameHostImpl) is leaked, RenderProcessHostImpl::Cleanup() aborts early, leaving browser_context_ as a dangling pointer when the associated profile is destroyed.
Standard processing applied for memory reclamation.
Jumping to the final exploitation phase: Invoking the media::mojom::VideoDecodePerfHistory Mojo interface via BindVideoDecodePerfHistory directly retrieves the dangling browser_context_ pointer. By controlling the reclaimed BrowserContext memory, the attacker dictates the impl_ pointer, causing GetVideoDecodePerfHistory() to return a fake object. The Mojo ReceiverSet::Add operation binds the receiver directly to this attacker-controlled fake object. Subsequent Mojo IPC messages routed to this receiver trigger virtual function calls (e.g., GetPerfInfo) using an attacker-supplied vtable, resulting in immediate arbitrary code execution in the browser process.
Evaluated with Chrome root at commit: 9760e6c70cd33a320713361f17c6dcca85648c0f
Results from Flapjack so far have been promising, but it can be wrong in its deductions. At this time, it does not produce proof of concepts or fuzzer tests. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve Flapjack’s accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.