00b6352a29c798f98e2925653692fd80c475f717 [M150] Prevent use-after-free in WidgetBase by adding weak pointer checks.
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 tothisbefore 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 onthis.
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
- Reachability — A focused editable element and normal main-frame/IME scheduling reach DidBeginMainFrame and ShowVirtualKeyboardOnElementFocus.
- Trigger — The synchronous text-input/keyboard update re-enters and destroys the WidgetBase before the method returns (inferred).
- Primitive — Execution continues on the freed WidgetBase, dereferencing client_ / member state (use-after-free).
- 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
- 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).
- Trigger — Cause the synchronous UpdateTextInputState/ShowVirtualKeyboard path to run and free the WidgetBase mid-method (inferred).
- Groom — Reoccupy the freed WidgetBase allocation with attacker-influenced data (inferred).
- 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
thisor 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.