Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in WebView
DescriptionUse after free in WebView
ComponentWebView
Bug ClassUAF
Tracker495507390
Fix commit0f34e380dfbc (chromium/src) +1/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-03-31

Files Changed

  • android_webview/browser/gfx/aw_draw_fn_impl.cc
From 0f34e380dfbc5ed33647e1d338611a7943be4423 Mon Sep 17 00:00:00 2001
From: Bo Liu <boliu@chromium.org>
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 <boliu@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
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 rj...@google.com

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