Critical watch CVSS 8.8 chrome UAF 📄 Reporter bug report 🔧 Commit mapped

Overview

Critical
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in File Input
DescriptionUse after free in File Input
ComponentFile Input
Sub-componentGtk
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.
Tracker520157118
Fix commit0852956e0551 (chromium/src) +4/-1
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-06-05 (per vendor advisory)
Fix landed2026-06-08 (public git)
Disclosed2026-06-16
Patch gap8 days — fix public in source before the advisory

Background

`SelectFileDialogLinuxGtk`
Chrome’s GTK-backed implementation of the native file open/save dialog on Linux; its destructor tears down any dialog widgets still tracked in dialogs_.
`GtkWindowDestroy()`
a helper that synchronously drops the last reference on a GTK dialog widget, disposing and finalizing it and returning its GLib heap allocation immediately.
`OnFileChooserDestroy()`
a cleanup routine that, per the commit message, calls g_object_set_data() on the dialog (to clear transient-parent metadata via ClearAuraTransientParent), which requires the widget to still be a live object.
Use-after-free (UAF)
accessing memory through a pointer after the underlying object has been freed, here reading/writing GLib object data on an already-finalized GtkWidget.

Root Cause Analysis

In the destructor loop that iterates over each tracked dialog in dialogs_, the pre-patch code called GtkWindowDestroy(dialog) first and only then called OnFileChooserDestroy(dialog). As the added comment states, GtkWindowDestroy() “synchronously drops the only reference and frees the dialog,” so by the time OnFileChooserDestroy(dialog) ran it operated on a widget that had already been finalized and returned to the GLib heap. Because OnFileChooserDestroy() accesses the freed dialog (through g_object_set_data() to clear transient-parent properties), this dereference of a dangling pointer is a use-after-free.

The fix reorders the two calls so OnFileChooserDestroy(dialog) runs while the widget is still alive, and only afterward is GtkWindowDestroy(dialog) invoked to free it. The invariant restored is that all accesses to dialog must precede the call that frees it.

Key insight
The single mistake is destroy-before-cleanup ordering: the object was freed by GtkWindowDestroy() before the cleanup that still touches it (OnFileChooserDestroy()) had run. The fix simply swaps the order so cleanup completes on the live object before the synchronous free.

Attack Path

  1. Open a native file dialog A page or renderer-driven flow (e.g. an <input type="file"> interaction) causes the browser process to create a GTK file-chooser dialog tracked in SelectFileDialogLinuxGtk::dialogs_.
  2. Trigger destructor with a live dialog The SelectFileDialogLinuxGtk is destroyed while one or more dialogs remain in dialogs_, entering the loop that tears each one down.
  3. Free-then-use on the GLib heap GtkWindowDestroy(dialog) synchronously finalizes and frees the widget, then OnFileChooserDestroy(dialog) dereferences the freed pointer via g_object_set_data(), reading/writing already-freed GLib heap memory (the use-after-free).
  4. Reclaim the freed allocation An attacker who can control GLib/browser-process heap allocations between the free and the stale access could place attacker-influenced data in the reclaimed slot so the g_object_set_data() access corrupts controlled state. (inferred) — the diff shows only the UAF, not any specific reclamation primitive.
  5. Escalate to memory corruption / code execution Controlled corruption of the freed object could be leveraged toward further memory corruption in the browser process. (inferred) — no escalation primitive is demonstrated by the patch.

Impact Assessment

An attacker gains a use-after-free of a GTK dialog widget on the GLib heap in the browser (privileged) process on Linux, triggered during file-dialog teardown. Preconditions are that a native file-chooser dialog exists and the owning SelectFileDialogLinuxGtk is destroyed while dialogs remain tracked. The vendor advisory rates this critical severity and does not report in-the-wild exploitation; NVD scores it CVSS 8.8. The advisory metadata classifies it as a use-after-free in File Input and does not state exploited-in-the-wild status or a severity rating.

Changed Functions

FunctionChangeNotes
for
ui/gtk/select_file_dialog_linux_gtk.cc
modified

Files Changed

  • ui/gtk/select_file_dialog_linux_gtk.cc

Audit Directions

  • Free-then-cleanup ordering
    Audit destructors and teardown loops for a synchronous free (GtkWindowDestroy, g_object_unref, delete) placed before cleanup callbacks that still dereference the same object; the freeing call must come last.
  • Synchronous GTK/GLib disposal
    Review other GTK-integrated code (dialogs, windows, transient-parent handling via ClearAuraTransientParent/g_object_set_data) where GtkWindowDestroy() or similar drops the last reference immediately, and confirm no later statement touches the widget.
  • Widget lifetime in tracked collections
    Inspect containers like dialogs_ where objects are iterated and destroyed, ensuring per-element cleanup fully completes on each live element before it is freed and that iterators/references are not used after the free.
From 0852956e05514f481fb7318d884e3b3a6b48ef79 Mon Sep 17 00:00:00 2001
From: Tom Anderson <thomasanderson@chromium.org>
Date: Mon, 08 Jun 2026 15:41:26 -0700
Subject: [PATCH] [Gtk] Fix Use-After-Free in SelectFileDialogLinuxGtk destructor

In SelectFileDialogLinuxGtk::~SelectFileDialogLinuxGtk(), calling
GtkWindowDestroy(dialog) synchronously disposes and finalizes the dialog
widget before OnFileChooserDestroy() runs. Because
OnFileChooserDestroy() accesses the dialog (specifically inside
ClearAuraTransientParent to clear transient parent properties), this
results in a use-after-free on the GLib heap.

This CL resolves this by running OnFileChooserDestroy() to clear
transient parent metadata before synchronously destroying the GtkWidget
with GtkWindowDestroy().

Fixed: 520157118
Change-Id: I15f8596e17fe54abdae95410066d125d702eb0a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7909293
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Auto-Submit: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1643498}
---

diff --git a/ui/gtk/select_file_dialog_linux_gtk.cc b/ui/gtk/select_file_dialog_linux_gtk.cc
index adf2a549..9e3390f 100644
--- a/ui/gtk/select_file_dialog_linux_gtk.cc
+++ b/ui/gtk/select_file_dialog_linux_gtk.cc
@@ -207,8 +207,11 @@
   }
   for (GtkWidget* dialog : dialogs) {
     CHECK(dialog);
-    GtkWindowDestroy(dialog);
+    // `GtkWindowDestroy()` synchronously drops the only reference and frees
+    // the dialog, so run `OnFileChooserDestroy()` (which calls
+    // `g_object_set_data()` on `dialog`) first to avoid a use-after-free.
     OnFileChooserDestroy(dialog);
+    GtkWindowDestroy(dialog);
   }
   CHECK(dialogs_.empty());
 }
Loading diff…

Original Bug Report

reported by vm...@google.com

Browser-Process Use-After-Free in SelectFileDialogLinuxGtk Destructor

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 heap use-after-free (UAF) vulnerability exists in the browser process of Chromium on Linux when using the GTK file chooser dialog. In the destructor of SelectFileDialogLinuxGtk, destroying the GTK widget synchronously frees the object, while a subsequent callback accesses the freed dialog pointer to clear the transient parent data. This results in a use-after-free on the GLib/system heap, bypassing PartitionAlloc and MiraclePtr protections.

Affected files:

  • ui/gtk/select_file_dialog_linux_gtk.cc

Estimated timestamp from git blame: 2021-03-26

Description

A potential heap Use-After-Free (UAF) vulnerability exists in the GTK file chooser implementation for Linux (ui/gtk/select_file_dialog_linux_gtk.cc). The bug is located in the destructor SelectFileDialogLinuxGtk::~SelectFileDialogLinuxGtk(), where a native GTK widget is synchronously destroyed, followed by an immediate access to the same widget pointer.

In SelectFileDialogLinuxGtk::~SelectFileDialogLinuxGtk():

  for (GtkWidget* dialog : dialogs) {
    CHECK(dialog);
    GtkWindowDestroy(dialog);
    OnFileChooserDestroy(dialog);
  }
  1. GtkWindowDestroy(dialog) dispatches to either gtk_window_destroy (GTK4) or gtk_widget_destroy (GTK3). Since Chromium does not hold any additional reference count (or g_object_ref) on the dialog, this synchronously triggers the GObject dispose and finalize phases, freeing the memory of the GtkWidget on the GLib/system heap.
  2. Immediately after, OnFileChooserDestroy(dialog) is called with the freed dialog pointer.
  3. Inside OnFileChooserDestroy, if state.parent (the native browser window) is non-null, it calls ClearAuraTransientParent:
void SelectFileDialogLinuxGtk::OnFileChooserDestroy(GtkWidget* dialog) {
  ...
  if (state.parent) {
    CHECK(dialog);
    ClearAuraTransientParent(dialog, state.parent, platform_);
    state.parent->RemoveObserver(this);
  }
  ...
}
  1. ClearAuraTransientParent executes g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, nullptr), which performs a G_IS_OBJECT check and dereferences the freed dialog pointer to clear the associated transient parent property on the GObject. This constitutes a Use-After-Free read and write outside of PartitionAlloc (thus unaffected by MiraclePtr/BackupRefPtr).

Potential Attack Scenario / Trigger Steps

Note: These are potential steps based on code analysis; our tooling does not currently have the capability to run a live exploit verification.

  1. Environment: Linux desktop using GTK where the org.freedesktop.portal.FileChooser DBus interface is version < 3 or unavailable, forcing SelectFileDialogLinuxPortal to fall back to SelectFileDialogLinuxGtk.
  2. Action: A web page requests a file dialog via showOpenFilePicker() under a user activation gesture, then immediately triggers a frame navigation (e.g., location = 'about:blank') shortly after.
  3. Navigation Cancellation: The navigation invalidates the document, causing WebContentsBasedCanceller to invoke the cancel callback, which calls FileSystemChooser::FileSelectionCanceled() -> delete this;.
  4. Destruction Sequence: ~FileSystemChooser invokes dialog_->ListenerDestroyed(), which resets fallback_dialog_ inside SelectFileDialogLinuxPortal, dropping the last remaining reference to SelectFileDialogLinuxGtk.
  5. UAF Trigger: ~SelectFileDialogLinuxGtk() executes, destroying the dialog with GtkWindowDestroy and subsequently dereferencing it inside OnFileChooserDestroy.

Suggested Fix

To resolve this issue, the lifetime management during destruction should be inverted. OnFileChooserDestroy(dialog) must be called before the widget is destroyed via GtkWindowDestroy(dialog). This ensures that all operations accessing the widget’s properties (such as clearing transient parent associations) are performed while the object’s memory is fully valid.

--- a/ui/gtk/select_file_dialog_linux_gtk.cc
+++ b/ui/gtk/select_file_dialog_linux_gtk.cc
@@ -207,8 +207,8 @@ SelectFileDialogLinuxGtk::~SelectFileDialogLinuxGtk() {
   }
   for (GtkWidget* dialog : dialogs) {
     CHECK(dialog);
-    GtkWindowDestroy(dialog);
     OnFileChooserDestroy(dialog);
+    GtkWindowDestroy(dialog);
   }
   CHECK(dialogs_.empty());
 }

Evaluated with Chrome root at commit: d8b226a3be7c9c1ac9240c09e14698866c82e4ac


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