CVE-2026-5288
Overview
Background
- Android WebView GPU path
android_webview/browser/gfx/aw_draw_fn_impl.ccimplements the draw-functor interface the Android framework calls to render WebView contents via the GPU, including a Vulkan backend.- `AwDrawFnImpl`
- the C++ object bound to a native draw functor; it owns GPU resources whose destruction order matters because some resources reference others.
- `vulkan_context_provider_`
- a reference-counted provider of the Vulkan device/context used for drawing.
- `scoped_secondary_cb_draw_`
- a scoped object associated with secondary command-buffer drawing that depends on the Vulkan context being alive while it exists.
Root Cause Analysis
The patch adds a single line, scoped_secondary_cb_draw_.reset();, immediately before vulkan_context_provider_.reset(); in a cleanup/teardown path of aw_draw_fn_impl.cc (the enclosing function name is not shown in the @@ -264,6 +264,7 @@ hunk header).
Before the fix, vulkan_context_provider_ was released while scoped_secondary_cb_draw_ was still alive; because the secondary command-buffer draw object depends on the Vulkan context, it was left holding a reference to a provider/context that could now be destroyed. When scoped_secondary_cb_draw_ was subsequently used or finally destroyed, it accessed the already-freed Vulkan context — a use-after-free.
The fix enforces correct teardown ordering: the dependent scoped_secondary_cb_draw_ is reset first, so it releases its hold on the Vulkan context before the provider is dropped, ensuring the context outlives everything that references it.
scoped_secondary_cb_draw_ before vulkan_context_provider_ so the dependency is torn down in the correct order.Attack Path
- Exercise the WebView Vulkan draw path
Render web content in an Android WebView configured for the Vulkan GPU backend so that
scoped_secondary_cb_draw_andvulkan_context_provider_are both live. - Trigger teardown
Cause the cleanup path containing the two
reset()calls to run (e.g., functor/context teardown), where the pre-patch order released the Vulkan context provider first. - Dangling dependent object
scoped_secondary_cb_draw_is left referencing the freed Vulkan context aftervulkan_context_provider_.reset(). - Use-after-free
Destruction/finalization of
scoped_secondary_cb_draw_dereferences the freed context, producing the reported UAF. Any controlled reuse, read/write primitive, or escalation is(inferred)and not shown by the patch.
Impact Assessment
(inferred).Files Changed
android_webview/browser/gfx/aw_draw_fn_impl.cc
Audit Directions
- Member destruction/reset orderingReview teardown paths that explicitly
reset()multiple owned members; verify objects that depend on a resource are released before the resource itself (manual order is easy to get backwards relative to declaration order). - Scoped helpers outliving their backing contextAudit “scoped”/RAII draw or command-buffer helpers that capture a provider/device; confirm their lifetime is strictly nested within the provider’s.
- GPU backend resource graphsAcross GPU backends (Vulkan/GL/Metal), look for context providers reset alongside command-buffer or draw objects, where a late-added member is not added to the explicit reset sequence.
Patch
From 0f34e380dfbc5ed33647e1d338611a7943be4423 Mon Sep 17 00:00:00 2001 From: Bo Liu <[email protected]> Date: Tue, 24 Mar 2026 07:02:38 -0700 Subject: [PATCH] aw: Fix AwDrawFnImpl UaF Bug: 495507390 Change-Id: I3c9fe826be5b36fb99cf7d38c9699c73d9342a00 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7697116 Auto-Submit: Bo Liu <[email protected]> Reviewed-by: Vasiliy Telezhnikov <[email protected]> Commit-Queue: Vasiliy Telezhnikov <[email protected]> Cr-Commit-Position: refs/heads/main@{#1604092} --- diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc index 666dd3be..673ada9 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.cc +++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc @@ -264,6 +264,7 @@ false /* abandon_context */); } + scoped_secondary_cb_draw_.reset(); vulkan_context_provider_.reset(); }
Original Bug Report
Potential UAF in AwDrawFnImpl leading to Sandbox Escape
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 Android WebView’s hardware-accelerated Vulkan drawing sequence. If a graphics context loss occurs mid-draw, a dangling raw pointer to a destroyed Vulkan context provider is left behind, which can be exploited for arbitrary code execution in the browser process.
Affected files:
android_webview/browser/gfx/aw_draw_fn_impl.ccandroid_webview/browser/gfx/aw_vulkan_context_provider.h
Estimated timestamp from git blame: 2025-06-24
Summary
A potential Use-After-Free (UAF) vulnerability has been identified in Android WebView’s hardware-accelerated Vulkan rendering path (android_webview/browser/gfx/aw_draw_fn_impl.cc). The vulnerability is caused by improper lifecycle management of the AwVulkanContextProvider object during a GPU context loss. Because Android WebView’s browser process does not have MiraclePtr (BackupRefPtr) enabled, this dangling pointer can be exploited to achieve arbitrary code execution (RCE) and a full sandbox escape.
Vulnerability Details
The AwDrawFnImpl class manages Vulkan rendering state using two key members:
scoped_refptr<AwVulkanContextProvider> vulkan_context_provider_;std::optional<AwVulkanContextProvider::ScopedSecondaryCBDraw> scoped_secondary_cb_draw_;
The Android Framework (HWUI) interacts with this class through a sequence of callbacks: InitVk, DrawVk, and PostDrawVk.
- State Population: When HWUI calls
AwDrawFnImpl::DrawVk, the method verifiesvulkan_context_provider_is valid and callsscoped_secondary_cb_draw_.emplace(...). This constructs aScopedSecondaryCBDrawobject, which stores araw_ptrto theAwVulkanContextProviderin itsprovider_field. - The Interruption: If a graphics context loss occurs between
DrawVkandPostDrawVk(e.g., triggered by an attacker exhausting GPU resources or forcing a TDR via WebGL), the Android Framework aborts the sequence and invokes theAwDrawFnImpl::OnContextDestroyedcallback. - The Flaw:
OnContextDestroyedcorrectly cleans up the hardware renderer and callsvulkan_context_provider_.reset();. This drops the primary reference count, destroying theAwVulkanContextProviderobject (which is 80 bytes on 64-bit systems). However, it crucially fails to resetscoped_secondary_cb_draw_. TheScopedSecondaryCBDrawobject remains active, holding a danglingraw_ptrto the freed 80-byte memory chunk. - Skipped Cleanup: HWUI eventually calls
AwDrawFnImpl::PostDrawVk. Becausevulkan_context_provider_is now null, the method returns early, skipping the intendedscoped_secondary_cb_draw_.reset();cleanup.
Potential Exploitation Steps
(Note: These are theoretical steps, as the Flapjack LLM agent cannot run code to verify an exploit.)
- Trigger UAF State: An attacker from a compromised renderer process forces a Vulkan draw sequence and simultaneously triggers a GPU context loss (e.g., via a complex WebGL shader or massive texture allocations), causing
OnContextDestroyedto execute mid-draw. - Heap Spray (Staging): The attacker reclaims the freed 80-byte memory chunk in the browser process heap. This can be achieved by spraying the 80-byte bucket using highly controllable allocations from the renderer, such as sending thousands of Mojo messages with a 32-byte V1 header and a 48-byte payload. The sprayed payload contains a forged
AwVulkanContextProviderstructure. - Forge Object State: The attacker crafts the forged object to control the
post_submit_tasks_vector (astd::vector<base::OnceClosure>) or theglobals_pointer. - Trigger Execution: The attacker forces the Android Framework to re-initialize the Vulkan context (calling
InitVk) and begin a new draw sequence (DrawVk). - Achieve RCE: When
DrawVkcallsscoped_secondary_cb_draw_.emplace(...), it destroys the previousScopedSecondaryCBDrawinstance. The destructor executesprovider_->SecondaryCMBDrawSubmitted();on the forged object. InsideSecondaryCMBDrawSubmitted, the code iterates over the forgedpost_submit_tasks_vector and executesstd::move(closure).Run();, giving the attacker arbitrary code execution in the browser process.
Suggested Fix
Explicitly reset scoped_secondary_cb_draw_ during context destruction to ensure the dangling pointer is eliminated before the AwVulkanContextProvider is freed.
void AwDrawFnImpl::OnContextDestroyed() {
{
RenderThreadManager::InsideHardwareReleaseReset release_reset(
&render_thread_manager_);
render_thread_manager_.DestroyHardwareRendererOnRT(
false /* abandon_context */);
}
// FIX: Reset the scoped draw state to destroy the dangling raw_ptr.
scoped_secondary_cb_draw_.reset();
vulkan_context_provider_.reset();
}
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.