High watch CVSS 9.6 chrome UAF 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
9.6
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in WebView
DescriptionUse after free in WebView
ComponentWebView
Sub-componentAw
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Tracker495507390
Fix commit0f34e380dfbc (chromium/src) +1/-0
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-03-23 · bounty NA (per vendor advisory)
Fix landed2026-03-24 (public git)
Disclosed2026-03-31
Patch gap7 days — fix public in source before the advisory

Background

Android WebView GPU path
android_webview/browser/gfx/aw_draw_fn_impl.cc implements 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.

Key insight
The single mistake was destruction ordering — the Vulkan context provider was released before a scoped object that depends on it; the fix resets scoped_secondary_cb_draw_ before vulkan_context_provider_ so the dependency is torn down in the correct order.

Attack Path

  1. 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_ and vulkan_context_provider_ are both live.
  2. 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.
  3. Dangling dependent object scoped_secondary_cb_draw_ is left referencing the freed Vulkan context after vulkan_context_provider_.reset().
  4. 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

On Android WebView with the Vulkan backend, driving the GPU draw-functor teardown can free the Vulkan context while a dependent scoped draw object still references it, causing a use-after-free in the WebView browser/GPU process. The vendor advisory rates this high severity and describes it as a use-after-free in WebView; it does not report in-the-wild exploitation, and the preconditions include the Vulkan rendering backend being active on the device. Escalation beyond freed-memory access (controlled reuse or code execution) is (inferred).

Files Changed

  • android_webview/browser/gfx/aw_draw_fn_impl.cc

Audit Directions

  • Member destruction/reset ordering
    Review 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 context
    Audit “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 graphs
    Across 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.
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();
 }
 
Loading diff…

Original Bug Report

reported by [email protected]

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.cc
  • android_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.

  1. State Population: When HWUI calls AwDrawFnImpl::DrawVk, the method verifies vulkan_context_provider_ is valid and calls scoped_secondary_cb_draw_.emplace(...). This constructs a ScopedSecondaryCBDraw object, which stores a raw_ptr to the AwVulkanContextProvider in its provider_ field.
  2. The Interruption: If a graphics context loss occurs between DrawVk and PostDrawVk (e.g., triggered by an attacker exhausting GPU resources or forcing a TDR via WebGL), the Android Framework aborts the sequence and invokes the AwDrawFnImpl::OnContextDestroyed callback.
  3. The Flaw: OnContextDestroyed correctly cleans up the hardware renderer and calls vulkan_context_provider_.reset();. This drops the primary reference count, destroying the AwVulkanContextProvider object (which is 80 bytes on 64-bit systems). However, it crucially fails to reset scoped_secondary_cb_draw_. The ScopedSecondaryCBDraw object remains active, holding a dangling raw_ptr to the freed 80-byte memory chunk.
  4. Skipped Cleanup: HWUI eventually calls AwDrawFnImpl::PostDrawVk. Because vulkan_context_provider_ is now null, the method returns early, skipping the intended scoped_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.)

  1. 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 OnContextDestroyed to execute mid-draw.
  2. 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 AwVulkanContextProvider structure.
  3. Forge Object State: The attacker crafts the forged object to control the post_submit_tasks_ vector (a std::vector<base::OnceClosure>) or the globals_ pointer.
  4. Trigger Execution: The attacker forces the Android Framework to re-initialize the Vulkan context (calling InitVk) and begin a new draw sequence (DrawVk).
  5. Achieve RCE: When DrawVk calls scoped_secondary_cb_draw_.emplace(...), it destroys the previous ScopedSecondaryCBDraw instance. The destructor executes provider_->SecondaryCMBDrawSubmitted(); on the forged object. Inside SecondaryCMBDrawSubmitted, the code iterates over the forged post_submit_tasks_ vector and executes std::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.

View on issue tracker