Package: release.debian.org
Severity: normal
Tags: trixie d-i
X-Debbugs-Cc: [email protected], [email protected]
Control: affects -1 + src:glib2.0
User: [email protected]
Usertags: pu

[ Reason ]
Fix CVE-2026-16118

[ Impact ]
Fixes something that upstream have treated as a vulnerability (although 
I'm unconvinced that it's practically exploitable on systems that aren't 
already compromised)

[ Tests ]
autopkgtests pass. Upgraded a trixie GNOME desktop system, it seems to 
work normally.

A test-build for amd64 and i386 (differing only in the changelog) is 
available at <https://people.debian.org/~smcv/13.7/glib2.0-deb13u5>.

[ Risks ]
I would say low risk, the changes are targeted and obvious.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
      - note that this assumes 2.84.4-3~deb13u4, 
        https://bugs.debian.org/1143852 was already accepted -
        please see that bug for the deb13u4 changes
  [x] the issue is verified as fixed in unstable

[ Changes ]
d/p/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch 
is probably not strictly required, but it was part of the upstream fix 
and is obviously harmless (it only touches test/debug code). The other 
patch is the actual bug fix.

[ Other info ]
Will need a d-i ack for the graphical installer. Includes the changes 
from 2.84.4-3~deb13u4 (https://bugs.debian.org/1143852), which I have 
not included in the debdiff here.
diffstat for glib2.0-2.84.4 glib2.0-2.84.4

 debian/changelog                                                                              |   15 +++
 debian/patches/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch |   46 ++++++++++
 debian/patches/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch       |   31 ++++++
 debian/patches/series                                                                         |    2 
 gio/xdgmime/xdgmime.c                                                                         |    3 
 gio/xdgmime/xdgmimemagic.c                                                                    |    8 -
 6 files changed, 100 insertions(+), 5 deletions(-)

diff -Nru glib2.0-2.84.4/debian/changelog glib2.0-2.84.4/debian/changelog
--- glib2.0-2.84.4/debian/changelog	2026-08-07 10:33:15.000000000 +0100
+++ glib2.0-2.84.4/debian/changelog	2026-08-23 15:20:28.000000000 +0100
@@ -1,3 +1,18 @@
+glib2.0 (2.84.4-3~deb13u5) trixie; urgency=medium
+
+  * Add patches from upstream 2.89.x to fix parsing of XDG MIME magic
+    datafiles
+    - d/p/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch:
+      Fix a crash when running tests on a minimal system
+    - d/p/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch:
+      Fix an out-of-bounds write if parsing attacker-controlled MIME-magic
+      data. This is unlikely to be exploitable in practice, because an
+      attacker with write access to $XDG_DATA_HOME/mime/magic is likely
+      to have other ways to cause arbitrary code execution.
+      (CVE-2026-16118, glib#3992 upstream, Closes: #1142717)
+
+ -- Simon McVittie <[email protected]>  Sun, 23 Aug 2026 15:20:28 +0100
+
 glib2.0 (2.84.4-3~deb13u4) trixie; urgency=medium
 
   * Edit previous changelog entry to correlate CVE fixes with upstream
diff -Nru glib2.0-2.84.4/debian/patches/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch glib2.0-2.84.4/debian/patches/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch
--- glib2.0-2.84.4/debian/patches/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.84.4/debian/patches/CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch	2026-08-23 15:20:28.000000000 +0100
@@ -0,0 +1,46 @@
+From: Kashyap Ekbote <[email protected]>
+Date: Wed, 5 Aug 2026 20:50:10 +0530
+Subject: Fix CVE-2026-16118: heap-buffer-overflow in xdgmimemagic.c
+
+Fix out-of-bounds write in the byte-swap routine of
+_xdg_mime_magic_parse_magic_line(). On little-endian systems, the
+write side of the swap casts the base pointer to a wider type before
+adding the byte offset, causing pointer arithmetic to scale by
+sizeof(type) instead of 1. With value_length=4 and word_size=2, the
+loop writes 2 bytes past the allocated matchlet->value buffer at i=2.
+
+Parenthesize (ptr + i) before the cast so both the read and write
+sides use byte offsets.
+
+Bug: https://gitlab.freedesktop.org/xdg/xdgmime/-/work_items/41
+Bug-CVE: https://security-tracker.debian.org/tracker/CVE-2026-16118
+Bug-Debian: https://bugs.debian.org/1142717
+Origin: upstream, 2.89.4, commit:ca75aff83af9875ea2ad2bfbe48a85dfd99c2ce5
+---
+ gio/xdgmime/xdgmimemagic.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/gio/xdgmime/xdgmimemagic.c b/gio/xdgmime/xdgmimemagic.c
+index 98a1274..fe374eb 100644
+--- a/gio/xdgmime/xdgmimemagic.c
++++ b/gio/xdgmime/xdgmimemagic.c
+@@ -483,15 +483,15 @@ _xdg_mime_magic_parse_magic_line (FILE              *magic_file,
+ 	  for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size)
+ 	    {
+ 	      if (matchlet->word_size == 2)
+-		*((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i)));
++		*((xdg_uint16_t *) (matchlet->value + i)) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i)));
+ 	      else if (matchlet->word_size == 4)
+-		*((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i)));
++		*((xdg_uint32_t *) (matchlet->value + i)) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i)));
+ 	      if (matchlet->mask)
+ 		{
+ 		  if (matchlet->word_size == 2)
+-		    *((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i)));
++		    *((xdg_uint16_t *) (matchlet->mask + i)) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i)));
+ 		  else if (matchlet->word_size == 4)
+-		    *((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i)));
++		    *((xdg_uint32_t *) (matchlet->mask + i)) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i)));
+ 
+ 		}
+ 	    }
diff -Nru glib2.0-2.84.4/debian/patches/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch glib2.0-2.84.4/debian/patches/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch
--- glib2.0-2.84.4/debian/patches/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.84.4/debian/patches/CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch	2026-08-23 15:20:28.000000000 +0100
@@ -0,0 +1,31 @@
+From: Philip Withnall <[email protected]>
+Date: Thu, 16 Jul 2026 12:55:56 +0100
+Subject: xdgmime: Check if caches are set before dumping them
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+This fixes a test failure when smoketesting the `fuzz_dump` test on a
+system where no xdgmime caches exist anywhere. The cache file generated
+by splitting README (for the smoketest) obviously isn’t valid.
+
+Signed-off-by: Philip Withnall <[email protected]>
+Origin: upstream, 2.89.4, commit:4ef012af942d517b84fac2d25c9031016818bb3d
+---
+ gio/xdgmime/xdgmime.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
+index 0909581..2e0bc79 100644
+--- a/gio/xdgmime/xdgmime.c
++++ b/gio/xdgmime/xdgmime.c
+@@ -950,7 +950,8 @@ xdg_mime_dump (void)
+   printf ("\n*** GLOBS ***\n\n");
+   _xdg_glob_hash_dump (global_hash);
+   printf ("\n*** GLOBS REVERSE TREE ***\n\n");
+-  _xdg_mime_cache_glob_dump ();
++  if (_caches)
++    _xdg_mime_cache_glob_dump ();
+ }
+ 
+ 
diff -Nru glib2.0-2.84.4/debian/patches/series glib2.0-2.84.4/debian/patches/series
--- glib2.0-2.84.4/debian/patches/series	2026-08-07 10:33:15.000000000 +0100
+++ glib2.0-2.84.4/debian/patches/series	2026-08-23 15:20:28.000000000 +0100
@@ -50,3 +50,5 @@
 tests-Improve-D-Bus-introspection-test-paths.patch
 gdbusintrospection-Fix-XML-parser-state-handling-for-node.patch
 fuzzing-Add-a-fuzz-test-for-g_dbus_node_info_new_for_xml.patch
+CVE-2026-16118/xdgmime-Check-if-caches-are-set-before-dumping-them.patch
+CVE-2026-16118/Fix-CVE-2026-16118-heap-buffer-overflow-in-xdgmimemagic.c.patch
diff -Nru glib2.0-2.84.4/gio/xdgmime/xdgmime.c glib2.0-2.84.4/gio/xdgmime/xdgmime.c
--- glib2.0-2.84.4/gio/xdgmime/xdgmime.c	2025-08-08 17:43:22.000000000 +0100
+++ glib2.0-2.84.4/gio/xdgmime/xdgmime.c	2026-08-23 15:24:50.000000000 +0100
@@ -950,7 +950,8 @@
   printf ("\n*** GLOBS ***\n\n");
   _xdg_glob_hash_dump (global_hash);
   printf ("\n*** GLOBS REVERSE TREE ***\n\n");
-  _xdg_mime_cache_glob_dump ();
+  if (_caches)
+    _xdg_mime_cache_glob_dump ();
 }
 
 
diff -Nru glib2.0-2.84.4/gio/xdgmime/xdgmimemagic.c glib2.0-2.84.4/gio/xdgmime/xdgmimemagic.c
--- glib2.0-2.84.4/gio/xdgmime/xdgmimemagic.c	2025-08-08 17:43:22.000000000 +0100
+++ glib2.0-2.84.4/gio/xdgmime/xdgmimemagic.c	2026-08-23 15:24:50.000000000 +0100
@@ -483,15 +483,15 @@
 	  for (i = 0; i < matchlet->value_length; i = i + matchlet->word_size)
 	    {
 	      if (matchlet->word_size == 2)
-		*((xdg_uint16_t *) matchlet->value + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i)));
+		*((xdg_uint16_t *) (matchlet->value + i)) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->value + i)));
 	      else if (matchlet->word_size == 4)
-		*((xdg_uint32_t *) matchlet->value + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i)));
+		*((xdg_uint32_t *) (matchlet->value + i)) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->value + i)));
 	      if (matchlet->mask)
 		{
 		  if (matchlet->word_size == 2)
-		    *((xdg_uint16_t *) matchlet->mask + i) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i)));
+		    *((xdg_uint16_t *) (matchlet->mask + i)) = SWAP_BE16_TO_LE16 (*((xdg_uint16_t *) (matchlet->mask + i)));
 		  else if (matchlet->word_size == 4)
-		    *((xdg_uint32_t *) matchlet->mask + i) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i)));
+		    *((xdg_uint32_t *) (matchlet->mask + i)) = SWAP_BE32_TO_LE32 (*((xdg_uint32_t *) (matchlet->mask + i)));
 
 		}
 	    }

Reply via email to