Overview

Critical
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in File Input
DescriptionUse after free in File Input
ComponentFile Input
Bug ClassUAF
Tracker520157118
Fix commit0852956e0551 (chromium/src) +4/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-16

Changed Functions

FunctionChangeNotes
for
ui/gtk/select_file_dialog_linux_gtk.cc
modified

Files Changed

  • ui/gtk/select_file_dialog_linux_gtk.cc
From 0852956e05514f481fb7318d884e3b3a6b48ef79 Mon Sep 17 00:00:00 2001
From: Tom Anderson <[email protected]>
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 <[email protected]>
Commit-Queue: Lei Zhang <[email protected]>
Auto-Submit: Thomas Anderson <[email protected]>
Reviewed-by: Lei Zhang <[email protected]>
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 [email protected]

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