CVE-2026-76023
Overview
Background
- `gtk-modules`
- a
GtkSettingsproperty listing GTK module names. GTK loads each listed module as a shared library into the process when the setting changes, so whoever controls the value controls which code is loaded. - XSETTINGS
- an X11 protocol in which a settings-manager client owns a selection and publishes desktop settings, including
Gtk/Modules; GTK applications on that display apply these updates live. - `GtkSettings` source priority
- each GTK setting records where its value came from. A value set by the application through
g_object_setgetsGTK_SETTINGS_SOURCE_APPLICATIONpriority, and lower-priority sources such as XSETTINGS cannot override it. - `GtkUi`
- Chrome’s Linux toolkit-theming layer in
ui/gtk, which initializes GTK inside the unsandboxed browser process to read themes, icons and settings.
Root Cause Analysis
Chrome’s Linux GTK integration runs in the unsandboxed browser process and keeps an X11 connection that GTK uses to receive XSETTINGS updates. Before the patch, Chrome never set gtk-modules itself, so the value stayed at a lower priority. Any XSETTINGS update carrying Gtk/Modules could therefore change it, and GTK would then load the named module libraries into the browser process. The commit message describes this as “executing untrusted GTK modules in the unsandboxed browser process via a retained X11 connection”. The invariant broken is that external, display-level settings must not be able to choose code to load into the browser process.
The fix adds g_object_set(settings, "gtk-modules", "", nullptr) to the initialization path that obtains gtk_settings_get_default(), before SanitizeIconThemeName()/SanitizeThemeName(). This sets the property to empty at GTK_SETTINGS_SOURCE_APPLICATION priority, so later XSETTINGS updates cannot replace it and no modules are loaded. It is a tightening: the setting changes from externally controllable to fixed to empty.
gtk-modules, a setting that loads shared libraries, be driven by lower-priority XSETTINGS from the X display, which handed library-loading control to whoever controlled that settings channel. Setting it to "" at application priority during initialization makes those updates ineffective.Attack Path
- Access to the X display The attacker needs to act as a client on the same X11 display Chrome uses, for example another local process able to claim or influence the XSETTINGS manager selection. This is a local, platform-specific position on Linux with GTK/X11, not something web content can reach.
- Publish malicious `Gtk/Modules`
The attacker’s settings manager sends an XSETTINGS update setting
Gtk/Modulesto a module name that resolves to an attacker-chosen library. How it resolves through GTK’s module search path is (inferred). - GTK applies the update in the browser
Before the fix, Chrome’s
GtkSettingsaccepted the lower-priority value because the application had never set the property. - Module loaded unsandboxed GTK loads the module into the unsandboxed browser process, giving code execution with the user’s browser privileges. The commit message states this outcome; full exploitation details are (inferred).
Impact Assessment
Files Changed
ui/gtk/gtk_ui.cc
Audit Directions
- Externally controlled GTK/GLib settingsReview other
GtkSettingsproperties and GLib/GIO mechanisms that load code or resources:gtk-im-module, input-method modules,GTK_MODULES/GTK_PATH-style environment, GIO extension points and theme engines. Check whether XSETTINGS,settings.inior environment can steer them in the browser process, and pin or sanitize them asSanitizeThemeName()does. - Live desktop-integration channels into the browser processAudit long-lived connections (X11, D-Bus, Wayland protocols, portal callbacks) through which another desktop client can push configuration into the unsandboxed browser. Treat each as a trust boundary and check that pushed values cannot trigger library loading or file execution.
- Ordering of hardening during initCheck that protective overrides such as
g_object_setpins and interceptors (InstallGtkSettingsInterceptor()) are applied before GTK processes any pending XSETTINGS events, so there is no early window where an unpinned value takes effect.
Patch
From 9ec61d5e14fff874426e560d593f93094c4377b7 Mon Sep 17 00:00:00 2001
From: Tom Anderson <thomasanderson@chromium.org>
Date: Wed, 12 Aug 2026 14:40:10 -0700
Subject: [PATCH] [ui/gtk] Pin gtk-modules to an empty string during initialization
Setting `gtk-modules` to `""` in GtkUi::Initialize() assigns
GTK_SETTINGS_SOURCE_APPLICATION priority to the setting, preventing
lower-priority XSETTINGS updates from overriding `gtk-modules` and
executing untrusted GTK modules in the unsandboxed browser process via a
retained X11 connection.
Fixed: 545124048
Change-Id: I91e1c3df94c0567c69eec676da26ee1bb46eca2f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8243490
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1678319}
---
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 68df09b..a688787 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -365,6 +365,9 @@
};
GtkSettings* settings = gtk_settings_get_default();
+ // Pin `gtk-modules` to an empty string with APPLICATION source priority
+ // to prevent XSETTINGS updates from loading GTK modules.
+ g_object_set(settings, "gtk-modules", "", nullptr);
SanitizeIconThemeName();
SanitizeThemeName();
InstallGtkSettingsInterceptor();
Original Bug Report
Sandbox escape: a compromised Linux/X11 GPU process can make GTK3 execute an attacker-controlled memfd in Chrome's browser process via Gtk/Modules
Report description
Sandbox escape: a compromised Linux/X11 GPU process can make GTK3 execute an attacker-controlled memfd in Chrome’s browser process via Gtk/Modules
Bug location
Where do you want to report your vulnerability?
Chrome VRP – Report security issues affecting the Chrome browser. See program rules
Which URL (or repository) have you found the vulnerability in?
https://chromium.googlesource.com/chromium/src/+/152.0.7977.30/ui/gtk/gtk_ui.cc
The problem
Please describe the technical details of the vulnerability
On Linux/X11 with GTK3, Chrome’s GPU process receives an X11 connection before the GPU sandbox is installed: creating a new connection after sandboxing requires socket operations that the sandbox blocks. A native attacker already executing in the GPU process can therefore use this retained authenticated X11 connection to become the per-screen XSETTINGS manager.
The affected sink is GTK3 module loading in Chrome’s unsandboxed browser process. GTK3 maps the XSETTING Gtk/Modules to the gtk-modules property. A dynamic XSETTING event writes that value directly to GTK private property storage unless Chrome has first made the property’s source APPLICATION. This dynamic path bypasses Chrome’s GtkSettings::set_property interceptor. GTK class notification then processes the module list: an absolute pathname is accepted by g_module_open, GTK resolves gtk_module_init, and invokes that initializer in the browser process.
Chrome Beta 152.0.7977.30 does not pin or clear gtk-modules; its current interceptor protects selected theme, icon, key, and cursor properties only. The effective attack sequence is:
native code in the already-compromised GPU process
-> use the retained authenticated X11 connection
-> become `_XSETTINGS_Sn` owner
-> create a compatible module in an executable memfd
-> publish `Gtk/Modules=/proc/<gpu-pid>/fd/<memfd>`
-> GTK3 in Chrome's browser process opens that path
-> GTK3 resolves and calls `gtk_module_init`
-> native code executes in the browser process
I dynamically verified the unmodified product sink on official Chrome for Testing Beta 152.0.7977.30 using a clean A/B/R campaign and normal Chrome sandbox settings:
- A / publish: the harmless module’s marker PID equaled the exact browser PID, differed from the publisher PID, and the exact executable memfd inode was mapped
r-xpin the browser process. - B / no publication: a fresh browser had neither marker nor target-module mapping.
- R / fresh repeat: the browser-PID marker and exact executable mapping recurred with a new publisher and new memfd inode.
The source and memfd SHA-256 values matched in each positive axis. This campaign used no browser patch, LD_PRELOAD, --no-sandbox, --disable-gpu-sandbox, or --disable-setuid-sandbox.
I also collected a separate three-run real-GPU post-filter discriminator. Each run recorded a real Chrome GPU PID with NoNewPrivs: 1, Seccomp: 2, one filter, a retained socket, successful executable-memfd staging after filter installation, XSETTINGS publication, browser-PID marker execution, and an executable browser mapping. That campaign deliberately uses disclosed preload / early-sandbox / dedicated-descriptor instrumentation to prove policy and ordering facts; it is not claimed to be an unmodified end-to-end product exploit.
The supplied PoC is source-only and uses a harmless module whose initializer records the exact PID. It demonstrates the unmodified product sink with an external X11 publisher analogue. It does not claim a renderer-to-GPU compromise, a Web trigger, or a full remote chain.
Proposed remediation
During GTK3 initialization, set gtk-modules to an empty application-owned value before dynamic XSETTING updates can be processed. GTK3’s source-precedence rule then rejects later XSETTING replacement. Adding only a setter-interceptor branch is insufficient because the dynamic XSETTING path writes GTK private storage directly.
An exact tagged Chromium candidate patch preserved XSETTINGS publication while suppressing both browser-PID module initialization and the target executable mapping; restoring the clean candidate reproduced both. This is candidate mitigation evidence, not a claim that a shipped fix exists.
Impact analysis
The attacker prerequisite is native code execution in Chrome’s already BPF-sandboxed Linux GPU process. Given that prerequisite, the attacker can cross the GPU sandbox boundary and cause native code execution in Chrome’s unsandboxed browser process by publishing one GTK XSETTING over the GPU process’s retained X11 connection.
The gain is browser-process native code execution, not merely a crash or parser-level behavior. A browser-process compromise is materially more privileged than code confined to the GPU sandbox and can expose browser-process capabilities available under the victim’s account. The report is therefore a GPU-sandbox escape / privilege-boundary violation.
The demonstrated scope is intentionally bounded: x86-64 Linux, Ozone/X11, GTK3, a retained authenticated X11 connection, compatible module ABI, and the tested same-UID /proc/<pid>/fd policy. I do not claim Wayland, GTK4, non-Linux platforms, universal /proc behavior, a renderer-to-GPU first stage, a Web-reachable trigger, or a complete remote exploitation chain. Recommended severity is High for the verified configuration; Google should apply its own VRP taxonomy.
The cause
What version of Chrome have you found the security issue in?
152.0.7977.30 Beta (Chrome for Testing; dynamically verified)
Is the security issue related to a crash?
No, it is not related to a crash.
Choose the type of vulnerability
Sandbox Escape
How would you like to be publicly acknowledged for your report?
Keita Sode (SYZD Research)