diff --git a/CVE-2025-13601.patch b/CVE-2025-13601.patch new file mode 100644 index 0000000..b010db3 --- /dev/null +++ b/CVE-2025-13601.patch @@ -0,0 +1,124 @@ +From 291b47380b2e0dd7c526bbde8d82ae6d739ef266 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 13 Nov 2025 18:27:22 +0000 +Subject: [PATCH] gconvert: Error out if g_escape_uri_string() would overflow + +If the string to escape contains a very large number of unacceptable +characters (which would need escaping), the calculation of the length of +the escaped string could overflow, leading to a potential write off the +end of the newly allocated string. + +In addition to that, the number of unacceptable characters was counted +in a signed integer, which would overflow to become negative, making it +easier for an attacker to craft an input string which would cause an +out-of-bounds write. + +Fix that by validating the allocation length, and using an unsigned +integer to count the number of unacceptable characters. + +Spotted by treeplus. Thanks to the Sovereign Tech Resilience programme +from the Sovereign Tech Agency. ID: #YWH-PGM9867-134 + +Signed-off-by: Philip Withnall + +Fixes: #3827 +--- + glib/gconvert.c | 36 +++++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 11 deletions(-) + +diff --git a/glib/gconvert.c b/glib/gconvert.c +index e7c222f8d..ffd860a83 100644 +--- a/glib/gconvert.c ++++ b/glib/gconvert.c +@@ -1338,8 +1338,9 @@ static const gchar hex[] = "0123456789ABCDEF"; + /* Note: This escape function works on file: URIs, but if you want to + * escape something else, please read RFC-2396 */ + static gchar * +-g_escape_uri_string (const gchar *string, +- UnsafeCharacterSet mask) ++g_escape_uri_string (const gchar *string, ++ UnsafeCharacterSet mask, ++ GError **error) + { + #define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask)) + +@@ -1347,7 +1348,7 @@ g_escape_uri_string (const gchar *string, + gchar *q; + gchar *result; + int c; +- gint unacceptable; ++ size_t unacceptable; + UnsafeCharacterSet use_mask; + + g_return_val_if_fail (mask == UNSAFE_ALL +@@ -1364,7 +1365,14 @@ g_escape_uri_string (const gchar *string, + if (!ACCEPTABLE (c)) + unacceptable++; + } +- ++ ++ if (unacceptable >= (G_MAXSIZE - (p - string)) / 2) ++ { ++ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, ++ _("The URI is too long")); ++ return NULL; ++ } ++ + result = g_malloc (p - string + unacceptable * 2 + 1); + + use_mask = mask; +@@ -1389,12 +1397,13 @@ g_escape_uri_string (const gchar *string, + + + static gchar * +-g_escape_file_uri (const gchar *hostname, +- const gchar *pathname) ++g_escape_file_uri (const gchar *hostname, ++ const gchar *pathname, ++ GError **error) + { + char *escaped_hostname = NULL; +- char *escaped_path; +- char *res; ++ char *escaped_path = NULL; ++ char *res = NULL; + + #ifdef G_OS_WIN32 + char *p, *backslash; +@@ -1415,10 +1424,14 @@ g_escape_file_uri (const gchar *hostname, + + if (hostname && *hostname != '\0') + { +- escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST); ++ escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST, error); ++ if (escaped_hostname == NULL) ++ goto out; + } + +- escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH); ++ escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH, error); ++ if (escaped_path == NULL) ++ goto out; + + res = g_strconcat ("file://", + (escaped_hostname) ? escaped_hostname : "", +@@ -1426,6 +1439,7 @@ g_escape_file_uri (const gchar *hostname, + escaped_path, + NULL); + ++out: + #ifdef G_OS_WIN32 + g_free ((char *) pathname); + #endif +@@ -1759,7 +1773,7 @@ g_filename_to_uri (const gchar *filename, + hostname = NULL; + #endif + +- escaped_uri = g_escape_file_uri (hostname, filename); ++ escaped_uri = g_escape_file_uri (hostname, filename, error); + + return escaped_uri; + } +-- +2.52.0 + diff --git a/RHEL-114857.patch b/gdbusconnection-serial-number-overflow.patch similarity index 100% rename from RHEL-114857.patch rename to gdbusconnection-serial-number-overflow.patch diff --git a/glib2.spec b/glib2.spec index 3bdb312..dbc3bdf 100644 --- a/glib2.spec +++ b/glib2.spec @@ -29,10 +29,19 @@ Patch: CVE-2024-52533.patch Patch: CVE-2025-4373.patch # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4470 -Patch: RHEL-114857.patch +Patch: gdbusconnection-serial-number-overflow.patch # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3933 -Patch: 0001-gappinfo-Allow-giving-no-GAppInfo-for-getting-startu.patch +Patch: startup-notify-without-gappinfo.patch + +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4914 +Patch: CVE-2025-13601.patch + +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4916 +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4918 +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4930 +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4931 +Patch: gunixmount-improvements.patch BuildRequires: gcc BuildRequires: gcc-c++ diff --git a/gunixmount-improvements.patch b/gunixmount-improvements.patch new file mode 100644 index 0000000..a934d72 --- /dev/null +++ b/gunixmount-improvements.patch @@ -0,0 +1,516 @@ +From e2de4e224a638918842e0578ddf4cb3101a2b0fa Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Fri, 21 Nov 2025 12:31:13 -0800 +Subject: [PATCH 1/5] gio/gunixmounts: mark some file-system types as system + +Since this list was originally created, more file system types have +become commonly used and would benefit from being marked as a system +file-system type. + +This was found while tracking down some performance issues in +gnome-settings-daemon trash handling. +--- + gio/gunixmounts.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c +index 6df984420..c15eb5f4e 100644 +--- a/gio/gunixmounts.c ++++ b/gio/gunixmounts.c +@@ -320,6 +320,8 @@ g_unix_is_system_fs_type (const char *fs_type) + "auto", + "autofs", + "autofs4", ++ "binfmt_misc", ++ "bpf", + "cgroup", + "configfs", + "cxfs", +@@ -328,6 +330,7 @@ g_unix_is_system_fs_type (const char *fs_type) + "devpts", + "devtmpfs", + "ecryptfs", ++ "efivarfs", + "fdescfs", + "fusectl", + "gfs", +@@ -356,6 +359,7 @@ g_unix_is_system_fs_type (const char *fs_type) + "selinuxfs", + "sysfs", + "tmpfs", ++ "tracefs", + "usbfs", + NULL + }; +-- +2.52.0 + + +From ccfc181691e5eda9d914473496f5f0e198e7364e Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Mon, 1 Dec 2025 15:36:02 +0100 +Subject: [PATCH 2/5] gio/gunixmounts: Mark more file systems as system + internal + +The commit f1a90a67 updated list of system internal file systems. +I think we can add a few more file systems (i.e. `cgroups2`, +`fuse.gvfsd-fuse`, `fuse.portal`) and `/bin/efi` path. This is to +improve performance of `gvfsd-trash`, `gsd-houskeeping` and similar. + +Related: https://gitlab.gnome.org/GNOME/gvfs/-/issues/814 +--- + gio/gunixmounts.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c +index c15eb5f4e..99a72e154 100644 +--- a/gio/gunixmounts.c ++++ b/gio/gunixmounts.c +@@ -239,6 +239,7 @@ g_unix_is_mount_path_system_internal (const char *mount_path) + */ + "/", /* we already have "Filesystem root" in Nautilus */ + "/bin", ++ "/bin/efi", + "/boot", + "/compat/linux/proc", + "/compat/linux/sys", +@@ -323,6 +324,7 @@ g_unix_is_system_fs_type (const char *fs_type) + "binfmt_misc", + "bpf", + "cgroup", ++ "cgroup2", + "configfs", + "cxfs", + "debugfs", +@@ -332,6 +334,8 @@ g_unix_is_system_fs_type (const char *fs_type) + "ecryptfs", + "efivarfs", + "fdescfs", ++ "fuse.gvfsd-fuse", ++ "fuse.portal", + "fusectl", + "gfs", + "gfs2", +-- +2.52.0 + + +From cfe7f8f178155bf12598583c6efeea55cb204c94 Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Wed, 3 Dec 2025 10:02:15 +0100 +Subject: [PATCH 3/5] gio/gunixmounts: Replace /bin/efi with /boot/efi + +The commit 06e9f2c0 added `/bin/efi` instead of `/boot/efi` to the +list of system internal mount paths by mistake. Let's fix it. +--- + gio/gunixmounts.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c +index 99a72e154..d51079b3b 100644 +--- a/gio/gunixmounts.c ++++ b/gio/gunixmounts.c +@@ -239,8 +239,8 @@ g_unix_is_mount_path_system_internal (const char *mount_path) + */ + "/", /* we already have "Filesystem root" in Nautilus */ + "/bin", +- "/bin/efi", + "/boot", ++ "/boot/efi", + "/compat/linux/proc", + "/compat/linux/sys", + "/dev", +-- +2.52.0 + + +From 6f0aa00dc242df965cc8a59f2dc9540911b3b61c Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Fri, 21 Nov 2025 18:54:33 -0800 +Subject: [PATCH 4/5] gio/unixmounts: use bsearch() to check for set inclusion + +This turns out to be about 17% faster than the previous set comparisons +on large (in the thousands) /proc/mounts configurations. It does require +that we keep the lists sorted but ended up faster than gperf hashing. +--- + gio/gunixmounts.c | 61 ++++++++++++++++++++++++----------------------- + 1 file changed, 31 insertions(+), 30 deletions(-) + +diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c +index d51079b3b..897c73ef9 100644 +--- a/gio/gunixmounts.c ++++ b/gio/gunixmounts.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -206,16 +207,17 @@ static GSource *proc_mounts_watch_source = NULL; + static struct libmnt_monitor *proc_mounts_monitor = NULL; + #endif + ++static int ++compare_str (const char * key, ++ const char * const *element) ++{ ++ return strcmp (key, *element); ++} ++ + static gboolean +-is_in (const char *value, const char *set[]) ++is_in (const char *value, const char *set[], gsize set_size) + { +- int i; +- for (i = 0; set[i] != NULL; i++) +- { +- if (strcmp (set[i], value) == 0) +- return TRUE; +- } +- return FALSE; ++ return bsearch (value, set, set_size, sizeof (char *), (GCompareFunc)compare_str) != NULL; + } + + /** +@@ -233,11 +235,12 @@ is_in (const char *value, const char *set[]) + gboolean + g_unix_is_mount_path_system_internal (const char *mount_path) + { ++ /* keep sorted for bsearch */ + const char *ignore_mountpoints[] = { + /* Includes all FHS 2.3 toplevel dirs and other specialized + * directories that we want to hide from the user. + */ +- "/", /* we already have "Filesystem root" in Nautilus */ ++ "/", /* we already have "Filesystem root" in Nautilus */ + "/bin", + "/boot", + "/boot/efi", +@@ -253,11 +256,15 @@ g_unix_is_mount_path_system_internal (const char *mount_path) + "/live/image", + "/media", + "/mnt", ++ "/net", + "/opt", ++ "/proc", + "/rescue", + "/root", + "/sbin", ++ "/sbin", + "/srv", ++ "/sys", + "/tmp", + "/usr", + "/usr/X11R6", +@@ -269,23 +276,21 @@ g_unix_is_mount_path_system_internal (const char *mount_path) + "/var", + "/var/crash", + "/var/local", +- GLIB_LOCALSTATEDIR, + "/var/log", + "/var/log/audit", /* https://bugzilla.redhat.com/show_bug.cgi?id=333041 */ + "/var/mail", + "/var/run", +- GLIB_RUNSTATEDIR, + "/var/tmp", /* https://bugzilla.redhat.com/show_bug.cgi?id=335241 */ +- "/proc", +- "/sbin", +- "/net", +- "/sys", +- NULL + }; + +- if (is_in (mount_path, ignore_mountpoints)) ++ if (is_in (mount_path, ignore_mountpoints, G_N_ELEMENTS (ignore_mountpoints))) + return TRUE; +- ++ ++ /* Kept separate from sorted list as they may vary */ ++ if (g_str_equal (GLIB_LOCALSTATEDIR, mount_path) || ++ g_str_equal (GLIB_RUNSTATEDIR, mount_path)) ++ return TRUE; ++ + if (g_str_has_prefix (mount_path, "/dev/") || + g_str_has_prefix (mount_path, "/proc/") || + g_str_has_prefix (mount_path, "/sys/")) +@@ -315,14 +320,13 @@ g_unix_is_mount_path_system_internal (const char *mount_path) + gboolean + g_unix_is_system_fs_type (const char *fs_type) + { ++ /* keep sorted for bsearch */ + const char *ignore_fs[] = { + "adfs", + "afs", + "auto", + "autofs", + "autofs4", +- "binfmt_misc", +- "bpf", + "cgroup", + "cgroup2", + "configfs", +@@ -332,7 +336,6 @@ g_unix_is_system_fs_type (const char *fs_type) + "devpts", + "devtmpfs", + "ecryptfs", +- "efivarfs", + "fdescfs", + "fuse.gvfsd-fuse", + "fuse.portal", +@@ -363,14 +366,12 @@ g_unix_is_system_fs_type (const char *fs_type) + "selinuxfs", + "sysfs", + "tmpfs", +- "tracefs", + "usbfs", +- NULL + }; + + g_return_val_if_fail (fs_type != NULL && *fs_type != '\0', FALSE); + +- return is_in (fs_type, ignore_fs); ++ return is_in (fs_type, ignore_fs, G_N_ELEMENTS (ignore_fs)); + } + + /** +@@ -392,19 +393,19 @@ g_unix_is_system_fs_type (const char *fs_type) + gboolean + g_unix_is_system_device_path (const char *device_path) + { ++ /* keep sorted for bsearch */ + const char *ignore_devices[] = { +- "none", +- "sunrpc", +- "devpts", +- "nfsd", + "/dev/loop", + "/dev/vn", +- NULL ++ "devpts", ++ "nfsd", ++ "none", ++ "sunrpc", + }; + + g_return_val_if_fail (device_path != NULL && *device_path != '\0', FALSE); + +- return is_in (device_path, ignore_devices); ++ return is_in (device_path, ignore_devices, G_N_ELEMENTS (ignore_devices)); + } + + static gboolean +-- +2.52.0 + + +From 182df8cc63f902288d377d9664dbf63448ca1cfe Mon Sep 17 00:00:00 2001 +From: Christian Hergert +Date: Tue, 6 Jan 2026 10:56:59 -0800 +Subject: [PATCH 5/5] gio/unixmounts: test that mounts are in sorted order + +--- + gio/gunixmounts-private.h | 69 +++++++++++++++++++++++++++++++++++++++ + gio/gunixmounts.c | 51 ++--------------------------- + gio/tests/unix-mounts.c | 25 ++++++++++++++ + 3 files changed, 96 insertions(+), 49 deletions(-) + create mode 100644 gio/gunixmounts-private.h + +diff --git a/gio/gunixmounts-private.h b/gio/gunixmounts-private.h +new file mode 100644 +index 000000000..196e81aca +--- /dev/null ++++ b/gio/gunixmounts-private.h +@@ -0,0 +1,69 @@ ++/* GIO - GLib Input, Output and Streaming Library ++ * ++ * Copyright 2006-2007 Red Hat, Inc. ++ * Copyright 2026 Christian Hergert ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++#pragma once ++ ++/* keep sorted for bsearch */ ++static const char *system_mount_paths[] = { ++ /* Includes all FHS 2.3 toplevel dirs and other specialized ++ * directories that we want to hide from the user. ++ */ ++ "/", /* we already have "Filesystem root" in Nautilus */ ++ "/bin", ++ "/boot", ++ "/compat/linux/proc", ++ "/compat/linux/sys", ++ "/dev", ++ "/etc", ++ "/home", ++ "/lib", ++ "/lib64", ++ "/libexec", ++ "/live/cow", ++ "/live/image", ++ "/media", ++ "/mnt", ++ "/net", ++ "/opt", ++ "/proc", ++ "/rescue", ++ "/root", ++ "/sbin", ++ "/sbin", ++ "/srv", ++ "/sys", ++ "/tmp", ++ "/usr", ++ "/usr/X11R6", ++ "/usr/local", ++ "/usr/obj", ++ "/usr/ports", ++ "/usr/src", ++ "/usr/xobj", ++ "/var", ++ "/var/crash", ++ "/var/local", ++ "/var/log", ++ "/var/log/audit", /* https://bugzilla.redhat.com/show_bug.cgi?id=333041 */ ++ "/var/mail", ++ "/var/run", ++ "/var/tmp", /* https://bugzilla.redhat.com/show_bug.cgi?id=335241 */ ++}; +diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c +index 897c73ef9..ec7c1e7d9 100644 +--- a/gio/gunixmounts.c ++++ b/gio/gunixmounts.c +@@ -76,6 +76,7 @@ extern char* hasmntopt(const struct mntent* mnt, const char* opt); + #endif + + #include "gunixmounts.h" ++#include "gunixmounts-private.h" + #include "gfile.h" + #include "gfilemonitor.h" + #include "glibintl.h" +@@ -235,55 +236,7 @@ is_in (const char *value, const char *set[], gsize set_size) + gboolean + g_unix_is_mount_path_system_internal (const char *mount_path) + { +- /* keep sorted for bsearch */ +- const char *ignore_mountpoints[] = { +- /* Includes all FHS 2.3 toplevel dirs and other specialized +- * directories that we want to hide from the user. +- */ +- "/", /* we already have "Filesystem root" in Nautilus */ +- "/bin", +- "/boot", +- "/boot/efi", +- "/compat/linux/proc", +- "/compat/linux/sys", +- "/dev", +- "/etc", +- "/home", +- "/lib", +- "/lib64", +- "/libexec", +- "/live/cow", +- "/live/image", +- "/media", +- "/mnt", +- "/net", +- "/opt", +- "/proc", +- "/rescue", +- "/root", +- "/sbin", +- "/sbin", +- "/srv", +- "/sys", +- "/tmp", +- "/usr", +- "/usr/X11R6", +- "/usr/local", +- "/usr/obj", +- "/usr/ports", +- "/usr/src", +- "/usr/xobj", +- "/var", +- "/var/crash", +- "/var/local", +- "/var/log", +- "/var/log/audit", /* https://bugzilla.redhat.com/show_bug.cgi?id=333041 */ +- "/var/mail", +- "/var/run", +- "/var/tmp", /* https://bugzilla.redhat.com/show_bug.cgi?id=335241 */ +- }; +- +- if (is_in (mount_path, ignore_mountpoints, G_N_ELEMENTS (ignore_mountpoints))) ++ if (is_in (mount_path, system_mount_paths, G_N_ELEMENTS (system_mount_paths))) + return TRUE; + + /* Kept separate from sorted list as they may vary */ +diff --git a/gio/tests/unix-mounts.c b/gio/tests/unix-mounts.c +index e3cc6c18c..98a3bcdfc 100644 +--- a/gio/tests/unix-mounts.c ++++ b/gio/tests/unix-mounts.c +@@ -30,6 +30,8 @@ + #include + #include + ++#include "../gunixmounts-private.h" ++ + static void + test_is_system_fs_type (void) + { +@@ -50,6 +52,28 @@ test_is_system_device_path (void) + g_assert_false (g_unix_is_system_device_path ("/")); + } + ++static void ++test_system_mount_paths_sorted (void) ++{ ++ size_t i; ++ size_t n_paths = G_N_ELEMENTS (system_mount_paths); ++ ++ g_test_summary ("Verify that system_mount_paths array is sorted for bsearch"); ++ ++ for (i = 1; i < n_paths; i++) ++ { ++ int cmp = strcmp (system_mount_paths[i - 1], system_mount_paths[i]); ++ if (cmp > 0) ++ { ++ g_test_fail_printf ("system_mount_paths array is not sorted: " ++ "\"%s\" should come before \"%s\"", ++ system_mount_paths[i - 1], ++ system_mount_paths[i]); ++ return; ++ } ++ } ++} ++ + int + main (int argc, + char *argv[]) +@@ -60,6 +84,7 @@ main (int argc, + + g_test_add_func ("/unix-mounts/is-system-fs-type", test_is_system_fs_type); + g_test_add_func ("/unix-mounts/is-system-device-path", test_is_system_device_path); ++ g_test_add_func ("/unix-mounts/system-mount-paths-sorted", test_system_mount_paths_sorted); + + return g_test_run (); + } +-- +2.52.0 + diff --git a/0001-gappinfo-Allow-giving-no-GAppInfo-for-getting-startu.patch b/startup-notify-without-gappinfo.patch similarity index 100% rename from 0001-gappinfo-Allow-giving-no-GAppInfo-for-getting-startu.patch rename to startup-notify-without-gappinfo.patch