← Chrome — 2026-W31

00b6352a29c798f98e2925653692fd80c475f717  [M150] Prevent use-after-free in WidgetBase by adding weak pointer checks.

severity high class UAF CVSS 8.1 signal score 16.7 AI review PLAUSIBLE
Structural signals: smartptr_member_added (+4.87), null_guard (+1.95), uaf_lifetime (+3.57), msg_strong (+3.0), msg_medium (+2.0), surgical (+1.3)

The bug at a glance

The diff adds weak-pointer guards after synchronous calls (UpdateTextInputState, ShowVirtualKeyboard) that can re-enter and destroy the WidgetBase, after which the code dereferenced client_ and continued executing on a freed this; a use-after-free in the renderer widget layer reachable from ordinary page/IME interaction is high severity.

An attacker-controlled page can arrange for a focus/IME or main-frame-begin event to synchronously tear down the owning widget (e.g. via a navigation or frame detach triggered during the text-input/keyboard update), then benefit from the subsequent dereference of freed memory.

Root cause

WidgetBase::DidBeginMainFrame called UpdateTextInputState() and WidgetBase::ShowVirtualKeyboardOnElementFocus called ShowVirtualKeyboard(); both can run synchronous script/IPC that destroys the WidgetBase. The original code then unconditionally used this (calling client_->DidBeginMainFrame() and continuing past the keyboard call), operating on a freed object. The fix captures a base::WeakPtr before the risky call and returns early if the weak pointer is invalidated, proving the object could be freed mid-method.

Key code

Weak-pointer guard added around a reentrant call that can free this

base::WeakPtr<WidgetBase> weak_this = weak_ptr_factory_.GetWeakPtr();
UpdateTextInputState();
if (!weak_this) {
  return;
}
client_->DidBeginMainFrame();

Patch walkthrough

  • third_party/blink/renderer/platform/widget/widget_base.cc — Two methods now snapshot a WeakPtr to this before a synchronous call (UpdateTextInputState / ShowVirtualKeyboard) that can destroy the WidgetBase, and bail out if the object was destroyed before touching member state (client_) again, eliminating a use-after-free on this.

Background

WidgetBase — Blink platform object backing a renderer widget, owning client_ and participating in the main-frame lifecycle and IME/text-input flow.

base::WeakPtr / weak_ptr_factory_ — Chromium idiom for detecting whether an object has been destroyed after a reentrant call; the WeakPtr evaluates false once the factory’s owner is gone.

Reentrancy via synchronous IME update — UpdateTextInputState and ShowVirtualKeyboard can run synchronous IPC/JS that leads to widget/frame destruction before control returns.

Vulnerability window

  1. Reachability — A focused editable element and normal main-frame/IME scheduling reach DidBeginMainFrame and ShowVirtualKeyboardOnElementFocus.
  2. Trigger — The synchronous text-input/keyboard update re-enters and destroys the WidgetBase before the method returns (inferred).
  3. Primitive — Execution continues on the freed WidgetBase, dereferencing client_ / member state (use-after-free).
  4. Escalation — Controlled reuse of the freed allocation could turn the stale access into memory corruption in the renderer (inferred).

Proof of concept

Conceptually: focus an editable element and drive an IME/virtual-keyboard update or a begin-main-frame while simultaneously causing the owning widget/frame to be torn down synchronously during that update (e.g. a reentrant navigation or frame detach), so control returns into a method still operating on the freed widget. No exploit code provided.

Exploitation

  1. Setup — Create a page with a focusable text field and script that can synchronously destroy the hosting widget/frame during an IME or frame callback (inferred).
  2. Trigger — Cause the synchronous UpdateTextInputState/ShowVirtualKeyboard path to run and free the WidgetBase mid-method (inferred).
  3. Groom — Reoccupy the freed WidgetBase allocation with attacker-influenced data (inferred).
  4. Corruption — Post-call dereference of client_/this reads/writes the reused memory, yielding a corruption primitive (inferred).

Detection & hunting

For defenders and detection engineers:

  • weggli/grep for methods calling UpdateTextInputState/ShowVirtualKeyboard or other reentrant sync calls followed by member/client_ use without a WeakPtr check — Flag call sites where a synchronous call that may run script/IPC is followed by further use of this or members with no GetWeakPtr()/!weak_this guard.
  • ASAN heap-use-after-free reports in WidgetBase::DidBeginMainFrame / ShowVirtualKeyboardOnElementFocus — Fuzz IME/focus/navigation interleavings and watch for UAF stacks in widget_base.cc.

Audit directions

  • third_party/blink/renderer/platform/widget/widget_base.cc and related widget/IME methods — Audit every method that makes a synchronous call capable of destroying the widget and then touches this/members, ensuring a WeakPtr guard exists.
  • Other Blink objects invoking synchronous text-input/IME/begin-frame callbacks — Look for the same destroy-during-callback pattern in InputMethodController, frame widget, and plugin/embed widget code.

Before / after

Loading diff…