Your message dated Fri, 23 May 2025 08:32:09 +0000
with message-id <e1uinp3-007rru...@respighi.debian.org>
and subject line unblock glib2.0
has caused the Debian Bug report #1104976,
regarding unblock: glib2.0/2.84.2-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1104976: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104976
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: 
X-Debbugs-Cc: glib...@packages.debian.org, debian-b...@lists.debian.org
Control: affects -1 + src:glib2.0
User: release.debian....@packages.debian.org
Usertags: unblock

[ Reason ]
CVE-2025-4373 (#1104930).

I also took the opportunity to catch up with the upstream glib-2-84 
branch by adding one unrelated bugfix commit (a 1-line change).

[ Impact ]
Fixes an out-of-bounds write if an attacker can somehow arrange for GLib 
to be acting on overwhelmingly large strings (half the address space in 
a single GString object, so 2GB for 32-bit processes).

Ensures that localtime_r() is not called without first calling tzset(), 
which has unspecified behaviour.

[ Tests ]
Not yet tested. I will run autopkgtests and boot a GNOME system with the 
proposed GLib before upload, and inform this bug if further changes are 
needed.

GLib has a quite thorough test suite in general, but CVE-2025-4373 is 
not covered by it, because exploiting the bug requires a huge memory 
allocation that will, in practice, usually fail.

[ Risks ]
I can't think of any. If there is a problem, these changes would be easy 
to revert.

[ 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 testing
      (preliminary diff, will need a `dch -r` before release)

[ Other info ]
Needs a d-i ack due to the GTK-based graphical installer.

unblock glib2.0/2.84.1-3
diff --git a/debian/changelog b/debian/changelog
index 7f9c9d65fc..67651dcdd7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,28 @@
+glib2.0 (2.84.1-3) UNRELEASED; urgency=medium
+
+  [ Jeremy BĂ­cha ]
+  * d/p/gfileutils-Preserve-mode-during-atomic-updates.patch:
+    Add a note that this fix for LP#2072586 was reverted in the upstream
+    2.84.x branch as a behaviour change. It was kept in 2.85.x,
+    and seems reasonable to keep for trixie.
+
+  [ Simon McVittie ]
+  * d/p/gfileutils-Preserve-mode-during-atomic-updates.patch:
+    Add a cross-reference to LP#2072586
+  * d/p/gstring-carefully-handle-gssize-parameters.patch,
+    d/p/gstring-Make-len_unsigned-unsigned.patch:
+    Add patches from upstream to fix a buffer underflow with very large
+    GString instances (Closes: #1104930, CVE-2025-4373)
+  * d/p/gdate-Call-tzset-before-localtime_r.patch:
+    Add patch from upstream to ensure that tzset() is called before
+    localtime_r(); otherwise the behaviour of localtime_r() is unspecified.
+  * These patches bring us up to date with upstream glib-2-84 branch commit
+    2.84.1-15-gb3de15acf9, excluding changes that are not relevant to
+    Debian architectures (macOS CI and Windows) and the revert of the fix
+    for LP#2072586 (discussed above).
+
+ -- Simon McVittie <s...@debian.org>  Fri, 09 May 2025 10:46:25 +0100
+
 glib2.0 (2.84.1-2) unstable; urgency=medium
 
   * Cherry-pick 2 commits from glib-2-84 branch (LP: #2072586)
diff --git a/debian/patches/gdate-Call-tzset-before-localtime_r.patch b/debian/patches/gdate-Call-tzset-before-localtime_r.patch
new file mode 100644
index 0000000000..05e378bfa6
--- /dev/null
+++ b/debian/patches/gdate-Call-tzset-before-localtime_r.patch
@@ -0,0 +1,24 @@
+From: Alessandro Astone <alessandro.ast...@canonical.com>
+Date: Wed, 30 Apr 2025 16:04:34 +0200
+Subject: gdate: Call tzset before localtime_r
+
+From `man 3 ctime`:
+  According to POSIX.1, localtime() is required to behave as though tzset(3)
+  was called, while localtime_r() does not have this requirement.
+  For portable code, tzset(3) should be called before localtime_r().
+---
+ glib/gdate.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/glib/gdate.c b/glib/gdate.c
+index ffc21f1..ed25ec3 100644
+--- a/glib/gdate.c
++++ b/glib/gdate.c
+@@ -1392,6 +1392,7 @@ _g_localtime (time_t timet, struct tm *out_tm)
+   gboolean success = TRUE;
+ 
+ #ifdef HAVE_LOCALTIME_R
++  tzset ();
+   if (!localtime_r (&timet, out_tm))
+     success = FALSE;
+ #else
diff --git a/debian/patches/gfileutils-Preserve-mode-during-atomic-updates.patch b/debian/patches/gfileutils-Preserve-mode-during-atomic-updates.patch
index 79e1c9c014..5d0771924c 100644
--- a/debian/patches/gfileutils-Preserve-mode-during-atomic-updates.patch
+++ b/debian/patches/gfileutils-Preserve-mode-during-atomic-updates.patch
@@ -13,6 +13,10 @@ Closes GNOME/dconf#76
 (cherry picked from commit 3cc0c0de33bc4b461e89b05d142e1ecf5f474317)
 
 Origin: upstream glib-2-84 branch, after 2.84.1
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/glib2.0/+bug/2072586
+Comment: This was actually reverted from the glib-2-84 branch but
+ it seems reasonable to keep it for trixie anyway
+ https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4608
 ---
  glib/gfileutils.c      | 25 +++++++++++++++++++++++--
  glib/tests/fileutils.c | 14 ++++++++++----
diff --git a/debian/patches/gstring-Make-len_unsigned-unsigned.patch b/debian/patches/gstring-Make-len_unsigned-unsigned.patch
new file mode 100644
index 0000000000..33b48bf796
--- /dev/null
+++ b/debian/patches/gstring-Make-len_unsigned-unsigned.patch
@@ -0,0 +1,25 @@
+From: Peter Bloomfield <peterbloomfi...@bellsouth.net>
+Date: Fri, 11 Apr 2025 05:52:33 +0000
+Subject: gstring: Make len_unsigned unsigned
+
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/3677
+Bug-CVE: CVE-2025-4373
+Bug-Debian: https://bugs.debian.org/1104930
+Origin: upstream, 2.84.2, commit:f32f4aea514e39086a2627e9483d841c9eeb9bc3
+---
+ glib/gstring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/glib/gstring.c b/glib/gstring.c
+index d79a484..2a399ee 100644
+--- a/glib/gstring.c
++++ b/glib/gstring.c
+@@ -928,7 +928,7 @@ g_string_overwrite_len (GString     *string,
+                         const gchar *val,
+                         gssize       len)
+ {
+-  gssize len_unsigned;
++  gsize len_unsigned;
+   gsize end;
+ 
+   g_return_val_if_fail (string != NULL, NULL);
diff --git a/debian/patches/gstring-carefully-handle-gssize-parameters.patch b/debian/patches/gstring-carefully-handle-gssize-parameters.patch
new file mode 100644
index 0000000000..95c83f41f7
--- /dev/null
+++ b/debian/patches/gstring-carefully-handle-gssize-parameters.patch
@@ -0,0 +1,119 @@
+From: Michael Catanzaro <mcatanz...@redhat.com>
+Date: Mon, 28 Apr 2025 16:03:08 +0000
+Subject: gstring: carefully handle gssize parameters
+
+Wherever we use gssize to allow passing -1, we need to ensure we don't
+overflow the value by assigning a gsize to it without checking if the
+size exceeds the maximum gssize. The safest way to do this is to just
+use normal gsize everywhere instead and use gssize only for the
+parameter.
+
+Our computers don't have enough RAM to write tests for this. I tried
+forcing string->len to high values for test purposes, but this isn't
+valid and will just cause out of bounds reads/writes due to
+string->allocated_len being unexpectedly small, so I don't think we can
+test this easily.
+
+(cherry picked from commit cc647f9e46d55509a93498af19659baf9c80f2e3)
+
+Co-authored-by: Michael Catanzaro <mcatanz...@redhat.com>
+Bug: https://gitlab.gnome.org/GNOME/glib/-/issues/3677
+Bug-CVE: CVE-2025-4373
+Bug-Debian: https://bugs.debian.org/1104930
+Origin: upstream, 2.84.2, commit:a47dc889463d73dd47ad428ac217e3d84f28e242
+---
+ glib/gstring.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/glib/gstring.c b/glib/gstring.c
+index 5279ed3..d79a484 100644
+--- a/glib/gstring.c
++++ b/glib/gstring.c
+@@ -480,8 +480,9 @@ g_string_insert_len (GString     *string,
+     return string;
+ 
+   if (len < 0)
+-    len = strlen (val);
+-  len_unsigned = len;
++    len_unsigned = strlen (val);
++  else
++    len_unsigned = len;
+ 
+   if (pos < 0)
+     pos_unsigned = string->len;
+@@ -778,10 +779,12 @@ g_string_insert_c (GString *string,
+   g_string_maybe_expand (string, 1);
+ 
+   if (pos < 0)
+-    pos = string->len;
++    pos_unsigned = string->len;
+   else
+-    g_return_val_if_fail ((gsize) pos <= string->len, string);
+-  pos_unsigned = pos;
++    {
++      pos_unsigned = pos;
++      g_return_val_if_fail (pos_unsigned <= string->len, string);
++    }
+ 
+   /* If not just an append, move the old stuff */
+   if (pos_unsigned < string->len)
+@@ -814,6 +817,7 @@ g_string_insert_unichar (GString  *string,
+                          gssize    pos,
+                          gunichar  wc)
+ {
++  gsize pos_unsigned;
+   gint charlen, first, i;
+   gchar *dest;
+ 
+@@ -855,15 +859,18 @@ g_string_insert_unichar (GString  *string,
+   g_string_maybe_expand (string, charlen);
+ 
+   if (pos < 0)
+-    pos = string->len;
++    pos_unsigned = string->len;
+   else
+-    g_return_val_if_fail ((gsize) pos <= string->len, string);
++    {
++      pos_unsigned = pos;
++      g_return_val_if_fail (pos_unsigned <= string->len, string);
++    }
+ 
+   /* If not just an append, move the old stuff */
+-  if ((gsize) pos < string->len)
+-    memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
++  if (pos_unsigned < string->len)
++    memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
+ 
+-  dest = string->str + pos;
++  dest = string->str + pos_unsigned;
+   /* Code copied from g_unichar_to_utf() */
+   for (i = charlen - 1; i > 0; --i)
+     {
+@@ -921,6 +928,7 @@ g_string_overwrite_len (GString     *string,
+                         const gchar *val,
+                         gssize       len)
+ {
++  gssize len_unsigned;
+   gsize end;
+ 
+   g_return_val_if_fail (string != NULL, NULL);
+@@ -932,14 +940,16 @@ g_string_overwrite_len (GString     *string,
+   g_return_val_if_fail (pos <= string->len, string);
+ 
+   if (len < 0)
+-    len = strlen (val);
++    len_unsigned = strlen (val);
++  else
++    len_unsigned = len;
+ 
+-  end = pos + len;
++  end = pos + len_unsigned;
+ 
+   if (end > string->len)
+     g_string_maybe_expand (string, end - string->len);
+ 
+-  memcpy (string->str + pos, val, len);
++  memcpy (string->str + pos, val, len_unsigned);
+ 
+   if (end > string->len)
+     {
diff --git a/debian/patches/series b/debian/patches/series
index 797de6b376..fe3988c90c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -16,3 +16,6 @@ workarounds/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch
 debian/girepository-Describe-the-Debian-specific-cross-prefixed-.patch
 gclosure-fix-ATOMIC_CHANGE_FIELD-to-read-vint-atomically.patch
 gfileutils-Preserve-mode-during-atomic-updates.patch
+gstring-carefully-handle-gssize-parameters.patch
+gstring-Make-len_unsigned-unsigned.patch
+gdate-Call-tzset-before-localtime_r.patch
diff --git a/glib/gdate.c b/glib/gdate.c
index ffc21f1b9b..ed25ec308c 100644
--- a/glib/gdate.c
+++ b/glib/gdate.c
@@ -1392,6 +1392,7 @@ _g_localtime (time_t timet, struct tm *out_tm)
   gboolean success = TRUE;
 
 #ifdef HAVE_LOCALTIME_R
+  tzset ();
   if (!localtime_r (&timet, out_tm))
     success = FALSE;
 #else
diff --git a/glib/gstring.c b/glib/gstring.c
index 5279ed3cca..2a399ee21f 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -480,8 +480,9 @@ g_string_insert_len (GString     *string,
     return string;
 
   if (len < 0)
-    len = strlen (val);
-  len_unsigned = len;
+    len_unsigned = strlen (val);
+  else
+    len_unsigned = len;
 
   if (pos < 0)
     pos_unsigned = string->len;
@@ -778,10 +779,12 @@ g_string_insert_c (GString *string,
   g_string_maybe_expand (string, 1);
 
   if (pos < 0)
-    pos = string->len;
+    pos_unsigned = string->len;
   else
-    g_return_val_if_fail ((gsize) pos <= string->len, string);
-  pos_unsigned = pos;
+    {
+      pos_unsigned = pos;
+      g_return_val_if_fail (pos_unsigned <= string->len, string);
+    }
 
   /* If not just an append, move the old stuff */
   if (pos_unsigned < string->len)
@@ -814,6 +817,7 @@ g_string_insert_unichar (GString  *string,
                          gssize    pos,
                          gunichar  wc)
 {
+  gsize pos_unsigned;
   gint charlen, first, i;
   gchar *dest;
 
@@ -855,15 +859,18 @@ g_string_insert_unichar (GString  *string,
   g_string_maybe_expand (string, charlen);
 
   if (pos < 0)
-    pos = string->len;
+    pos_unsigned = string->len;
   else
-    g_return_val_if_fail ((gsize) pos <= string->len, string);
+    {
+      pos_unsigned = pos;
+      g_return_val_if_fail (pos_unsigned <= string->len, string);
+    }
 
   /* If not just an append, move the old stuff */
-  if ((gsize) pos < string->len)
-    memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
+  if (pos_unsigned < string->len)
+    memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
 
-  dest = string->str + pos;
+  dest = string->str + pos_unsigned;
   /* Code copied from g_unichar_to_utf() */
   for (i = charlen - 1; i > 0; --i)
     {
@@ -921,6 +928,7 @@ g_string_overwrite_len (GString     *string,
                         const gchar *val,
                         gssize       len)
 {
+  gsize len_unsigned;
   gsize end;
 
   g_return_val_if_fail (string != NULL, NULL);
@@ -932,14 +940,16 @@ g_string_overwrite_len (GString     *string,
   g_return_val_if_fail (pos <= string->len, string);
 
   if (len < 0)
-    len = strlen (val);
+    len_unsigned = strlen (val);
+  else
+    len_unsigned = len;
 
-  end = pos + len;
+  end = pos + len_unsigned;
 
   if (end > string->len)
     g_string_maybe_expand (string, end - string->len);
 
-  memcpy (string->str + pos, val, len);
+  memcpy (string->str + pos, val, len_unsigned);
 
   if (end > string->len)
     {

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply via email to