Overview

Critical
Severity
9.6
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Aura
DescriptionUse after free in Aura
ComponentAura
Sub-componentAura
Bug ClassUAF
Action tierpatch-now — corruption primitive, web-reachable in default config (confirmed) — upheld by independent review by AI
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.
Independent review by AIConfirmed
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker532921800
Fix commit6c6a101bf9d2 (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-07-09 (per vendor advisory)
Fix landed2026-07-25 (public git)
Disclosed2026-08-25
Patch gap31 days — fix public in source before the advisory

Background

`aura::Window`
The Aura windowing primitive that owns UI state and hosts the RenderWidgetHostViewEventHandler, whose lifetime is tied to the compositor and can be torn down during event processing.
`RenderWidgetHostViewEventHandler`
The browser-side helper that translates Aura input events for a render widget and implements pointer-locking logic in LockPointer.
`ScopedDeleteBlocker`
An aura::Window RAII guard that defers destruction of a window while the guard is in scope, preventing premature deletion during a re-entrant call.
`LockMouse`
The WindowTreeHost operation invoked from LockPointer that captures the pointer and may synchronously run code capable of destroying the originating window_.

Root Cause Analysis

RenderWidgetHostViewEventHandler::LockPointer sets mouse_locked_ = true and then calls window_->GetHost()->LockMouse(window_) on the raw window_ pointer. LockMouse can synchronously re-enter code that deletes window_ (and, by ownership, the RenderWidgetHostViewEventHandler itself), because acquiring the pointer lock may run focus, capture, or host-platform callbacks that tear down the widget. When LockMouse returns, LockPointer continues to dereference the now-freed window_ and its own member state (for example the ShouldMoveToCenter path), operating on freed memory. The invariant violated is that LockPointer assumes window_ and this remain valid across the nested LockMouse call.

The fix constructs an aura::Window::ScopedDeleteBlocker delete_blocker(window_) immediately before LockMouse, so any deletion request during the call is deferred until the guard unwinds, keeping window_ and the event handler alive through the rest of the method.

Key insight
The single mistake is invoking the re-entrant LockMouse on a raw window_ pointer whose deletion during the call also frees the enclosing RenderWidgetHostViewEventHandler; the fix pins the window’s lifetime with a scoped aura::Window::ScopedDeleteBlocker so the object graph survives until LockPointer finishes.

Attack Path

  1. Trigger pointer lock A malicious page requests pointer lock, causing the browser to call RenderWidgetHostViewEventHandler::LockPointer on the target window_.
  2. Enter re-entrant LockMouse LockPointer sets mouse_locked_ and synchronously calls window_->GetHost()->LockMouse(window_), which runs host-platform/focus callbacks.
  3. Destroy the window mid-call During those callbacks the attacker arranges for window_ (and thus the owning RenderWidgetHostViewEventHandler) to be deleted, freeing the objects while LockPointer is still on the stack.
  4. Use freed memory Control returns to LockPointer, which continues to dereference the freed window_ and this (e.g. the ShouldMoveToCenter branch), yielding a use-after-free that a crafted heap layout can turn into control-flow corruption.

Impact Assessment

An attacker who can drive pointer-lock requests from a compromised or malicious renderer gains a use-after-free in the browser process, where the freed aura::Window and RenderWidgetHostViewEventHandler memory is reused after LockMouse returns. Exploitation runs in the privileged browser (Aura) context and requires the ability to cause window_ deletion during the nested LockMouse call, making it a strong primitive for sandbox escape when combined with heap grooming.

Files Changed

  • content/browser/renderer_host/render_widget_host_view_event_handler.cc

Audit Directions

  • Re-entrant host calls on raw window pointers
    Audit other RenderWidgetHostViewEventHandler and Aura call sites that invoke WindowTreeHost/LockMouse-style methods on window_ and keep using window_ or this afterward without a lifetime guard.
  • Self-owning callbacks
    Look for methods where a synchronous call can delete the object that owns the current this, and verify a ScopedDeleteBlocker or WeakPtr recheck protects state touched after the call returns.
  • Pointer/input lock lifecycles
    Review pointer-lock, capture, and focus transitions that run nested platform callbacks, since these are common places where an aura::Window can be destroyed mid-operation.
From 6c6a101bf9d2dac667054f54220cfc046af40883 Mon Sep 17 00:00:00 2001
From: Mitsuru Oshima <oshima@chromium.org>
Date: Sat, 25 Jul 2026 07:38:18 -0700
Subject: [PATCH] aura: Handle window deletion during LockPointer

Use an aura::Window::ScopedDeleteBlocker in
RenderWidgetHostViewEventHandler::LockPointer to ensure that the window
(and by extension, the event handler) are not deleted prematurely while
executing.

Just checking weakptr in
RenderWidgetHostViewEventHandler and WindowTreeHostPlatform
as suggested in the bug is not enough(see bug). If we find a valid
use case for this deletion, we'll work on a different approach.

Bug: 532921800
Test: covered by unittest
TAG=agy
CONV=6a632318-b810-4c6e-a0e2-1135bf67758d

Change-Id: Iffe955d91dd88a2f99bf36d83517dc64d36da7a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8140414
Reviewed-by: Alex Moshchuk <alexmos@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1668283}
---
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
index 5fc3b632..36dcb04 100644
--- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc
+++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -148,6 +148,7 @@
   }
   mouse_locked_ = true;
 
+  aura::Window::ScopedDeleteBlocker delete_blocker(window_);
   window_->GetHost()->LockMouse(window_);
 
   if (ShouldMoveToCenter(unlocked_global_mouse_position_))
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential Use-After-Free in WindowTreeHostPlatform::LockMouse and RenderWidgetHostViewEventHandler

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential Use-After-Free vulnerability exists in the browser process of Aura-based platforms due to reentrant window destruction during mouse locking. Invoking SetCapture() can synchronously delete the capture window and its associated event handler during touch cancellation. This can result in a Use-After-Free when the deleted window or event handler is subsequently accessed.

Affected files:

  • ui/aura/window_tree_host_platform.cc
  • content/browser/renderer_host/render_widget_host_view_event_handler.cc
  • ui/aura/window_tree_host.cc

Estimated timestamp from git blame: 2021-07-02

Potential Use-After-Free in WindowTreeHostPlatform::LockMouse and RenderWidgetHostViewEventHandler

Description and Root Cause

A potential Use-After-Free (UAF) vulnerability exists in the browser process of Aura-based platforms (such as Linux, ChromeOS, and Fuchsia). The issue arises due to synchronous, reentrant window and view destruction during pointer locking.

Specifically, in WindowTreeHostPlatform::LockMouse (ui/aura/window_tree_host_platform.cc:226):

void WindowTreeHostPlatform::LockMouse(Window* window) {
  window->SetCapture();
  WindowTreeHost::LockMouse(window);
}

Calling window->SetCapture() can trigger a synchronous touch-cancellation flow via the gesture recognizer (ui/events/gestures/gesture_recognizer_impl.cc), which dispatches synthetic touch-cancel events (EventType::kTouchCancelled) to other active gesture consumers.

If a touch-cancel handler on another window synchronously destroys the requesting tab’s WebContents (e.g., closing a popup/dropdown or destroying the tab’s container), the target RenderWidgetHostViewAura view and its associated RenderWidgetHostViewEventHandler will be synchronously deleted.

When control returns to WindowTreeHostPlatform::LockMouse, the stack parameter window is now a dangling pointer. Furthermore, when execution returns to RenderWidgetHostViewEventHandler::LockPointer (content/browser/renderer_host/render_widget_host_view_event_handler.cc:151), both this and window_ are dangling:

  window_->GetHost()->LockMouse(window_);

  if (ShouldMoveToCenter(unlocked_global_mouse_position_)) // UAF read on this->unlocked_global_mouse_position_
    MoveCursorToCenter(nullptr);

  delegate_->SetTooltipsEnabled(false); // UAF dereference and virtual function call on this->delegate_

The subsequent call to delegate_->SetTooltipsEnabled(false) constitutes a virtual method call on a pointer (delegate_) read from freed memory. If an attacker reclaims this heap allocation before this line, it can lead to control-flow hijack and arbitrary code execution in the context of the unsandboxed browser process.

Affected Platforms

  • Linux, ChromeOS, and Fuchsia (Aura-based platforms).
  • Windows is unaffected because DesktopWindowTreeHostWin::LockMouse does not call SetCapture().

Potential Trigger Steps

Because our tooling agent does not currently have the ability to run or execute code, these are potential steps to trigger the issue:

  1. Setup active touch state: Arrange the browser UI state such that a gesture consumer on another window has an active touch.
  2. Initiate mouse lock: From the renderer process, trigger a pointer-lock request (e.g., via element.requestPointerLock()).
  3. Handle touch cancellation synchronously: When the gesture recognizer dispatches EventType::kTouchCancelled to the other consumer window during the SetCapture() call, its event handler must synchronously close or destroy the target WebContents/tab (for example, by dismissing an anchored popup bubble that owns or is bound to the target view).
  4. Trigger UAF: On shipping channels <= M151 (prior to M152 where a diagnostic CHECK was introduced), the deletion of the RenderWidgetHostViewEventHandler proceeds silently, and control returns to trigger the Use-After-Free reads and the virtual call dereference.

Suggested Fix

To resolve this issue, lifetime tracking should be introduced in both WindowTreeHostPlatform::LockMouse and RenderWidgetHostViewEventHandler::LockPointer to guard against reentrant destruction.

  1. In WindowTreeHostPlatform::LockMouse, track the Window lifetime using a base::WeakPtr<aura::Window> or WindowTracker:
void WindowTreeHostPlatform::LockMouse(Window* window) {
  base::WeakPtr<Window> window_weak = window->GetWeakPtrAsWindow();
  window->SetCapture();
  if (!window_weak)
    return;
  WindowTreeHost::LockMouse(window);
}
  1. In RenderWidgetHostViewEventHandler::LockPointer, similarly track the lifetime of this and window_ after the reentrant call:
  base::WeakPtr<RenderWidgetHostViewEventHandler> weak_this = weak_ptr_factory_.GetWeakPtr();
  window_->GetHost()->LockMouse(window_);

  if (!weak_this)
    return blink::mojom::PointerLockResult::kUnknown; // Or appropriate error

  if (ShouldMoveToCenter(unlocked_global_mouse_position_))
    MoveCursorToCenter(nullptr);

  delegate_->SetTooltipsEnabled(false);

Evaluated with Chrome root at commit: 84065d9121f6e48f67755f0ae963cc09617e5c85


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve 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