Bug#1103051: bookworm-pu: package glib2.0/2.74.6-2+deb12u6
Package: release.debian.org Severity: normal Tags: bookworm User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: secur...@debian.org, Debian GNOME Maintainers
* CVE-2025-3360: Integer overflow in g_date_time_new_from_iso8601()
diffstat for glib2.0-2.74.6 glib2.0-2.74.6 changelog | 7 patches/0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch | 55 +++++++ patches/0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch | 51 ++++++ patches/0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch | 35 ++++ patches/0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch | 75 ++++++++++ patches/0005-gdatetime-Factor-out-an-undersized-variable.patch | 56 +++++++ patches/series | 5 7 files changed, 284 insertions(+) diff -Nru glib2.0-2.74.6/debian/changelog glib2.0-2.74.6/debian/changelog --- glib2.0-2.74.6/debian/changelog 2024-11-14 11:42:34.000000000 +0200 +++ glib2.0-2.74.6/debian/changelog 2025-04-12 16:52:16.000000000 +0300 @@ -1,3 +1,10 @@ +glib2.0 (2.74.6-2+deb12u6) bookworm; urgency=medium + + * Non-maintainer upload. + * CVE-2025-3360: Integer overflow in g_date_time_new_from_iso8601() + + -- Adrian BunkSat, 12 Apr 2025 16:52:16 +0300 + glib2.0 (2.74.6-2+deb12u5) bookworm; urgency=medium * d/p/gsocks4aproxy-Fix-a-single-byte-buffer-overflow-in-connec.patch: diff -Nru glib2.0-2.74.6/debian/patches/0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch glib2.0-2.74.6/debian/patches/0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch --- glib2.0-2.74.6/debian/patches/0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch 1970-01-01 02:00:00.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch 2025-04-12 16:51:53.000000000 +0300 @@ -0,0 +1,55 @@ +From ea9e2896ce894e660cfe5c9bef6f17c3e9ad56f0 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Feb 2025 16:44:58 +0000 +Subject: gdatetime: Fix integer overflow when parsing very long ISO8601 inputs + +This will only happen with invalid (or maliciously invalid) potential +ISO8601 strings, but `g_date_time_new_from_iso8601()` needs to be robust +against that. + +Prevent `length` overflowing by correctly defining it as a `size_t`. +Similarly for `date_length`, but additionally track its validity in a +boolean rather than as its sign. + +Spotted by chamalsl as #YWH-PGM9867-43. + +Signed-off-by: Philip Withnall +--- + glib/gdatetime.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index a9c472e55..92a313418 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -1497,7 +1497,8 @@ parse_iso8601_time (const gchar *text, gsize length, + GDateTime * + g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz) + { +- gint length, date_length = -1; ++ size_t length, date_length = 0; ++ gboolean date_length_set = FALSE; + gint hour = 0, minute = 0; + gdouble seconds = 0.0; + GTimeZone *tz = NULL; +@@ -1508,11 +1509,14 @@ g_date_time_new_from_iso8601 (const gchar *text, GTimeZone *default_tz) + /* Count length of string and find date / time separator ('T', 't', or ' ') */ + for (length = 0; text[length] != '\0'; length++) + { +- if (date_length < 0 && (text[length] == 'T' || text[length] == 't' || text[length] == ' ')) +- date_length = length; ++ if (!date_length_set && (text[length] == 'T' || text[length] == 't' || text[length] == ' ')) ++ { ++ date_length = length; ++ date_length_set = TRUE; ++ } + } + +- if (date_length < 0) ++ if (!date_length_set) + return NULL; + + if (!parse_iso8601_time (text + date_length + 1, length - (date_length + 1), +-- +2.30.2 + diff -Nru glib2.0-2.74.6/debian/patches/0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch glib2.0-2.74.6/debian/patches/0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch --- glib2.0-2.74.6/debian/patches/0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch 1970-01-01 02:00:00.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch 2025-04-12 16:51:53.000000000 +0300 @@ -0,0 +1,51 @@ +From 4b9f757cc261c0163ffaaad69b73826604f2360a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Feb 2025 16:51:36 +0000 +Subject: gdatetime: Fix potential integer overflow in timezone offset handling + +This one is much harder to trigger than the one in the previous commit, +but mixing `gssize` and `gsize` always runs the risk of the former +overflowing for very (very very) long input strings. + +Avoid that possibility by not using the sign of the `tz_offset` to +indicate its validity, and instead using the return value of the +function. + +Signed-off-by: Philip Withnall +--- + glib/gdatetime.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index 92a313418..5c4ad461d 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -1346,8 +1346,10 @@ parse_iso8601_date (const gchar *text, gsize length, + return FALSE; + } + ++/* Value returned in tz_offset is valid if and only if the function return value ++ * is non-NULL. */ + static GTimeZone * +-parse_iso8601_timezone (const gchar *text, gsize length, gssize *tz_offset) ++parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + { + gint i, tz_length, offset_hours, offset_minutes; + gint offset_sign = 1; +@@ -1415,11 +1417,11 @@ static gboolean + parse_iso8601_time (const gchar *text, gsize length, + gint *hour, gint *minute, gdouble *seconds, GTimeZone **tz) + { +- gssize tz_offset = -1; ++ size_t tz_offset = 0; + + /* Check for timezone suffix */ + *tz = parse_iso8601_timezone (text, length, &tz_offset); +- if (tz_offset >= 0) ++ if (*tz != NULL) + length = tz_offset; + + /* hh:mm:ss(.sss) */ +-- +2.30.2 + diff -Nru glib2.0-2.74.6/debian/patches/0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch glib2.0-2.74.6/debian/patches/0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch --- glib2.0-2.74.6/debian/patches/0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch 1970-01-01 02:00:00.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch 2025-04-12 16:51:53.000000000 +0300 @@ -0,0 +1,35 @@ +From 495713b68813a76e31dd34c3592ddfd269c6def0 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Feb 2025 16:55:18 +0000 +Subject: gdatetime: Track timezone length as an unsigned size_t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It’s guaranteed to be in (0, length] by the calculations above. + +This avoids the possibility of integer overflow through `gssize` not +being as big as `size_t`. + +Signed-off-by: Philip Withnall +--- + glib/gdatetime.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index 5c4ad461d..72b8d04c6 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -1351,7 +1351,8 @@ parse_iso8601_date (const gchar *text, gsize length, + static GTimeZone * + parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + { +- gint i, tz_length, offset_hours, offset_minutes; ++ size_t tz_length; ++ gint i, offset_hours, offset_minutes; + gint offset_sign = 1; + GTimeZone *tz; + +-- +2.30.2 + diff -Nru glib2.0-2.74.6/debian/patches/0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch glib2.0-2.74.6/debian/patches/0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch --- glib2.0-2.74.6/debian/patches/0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch 1970-01-01 02:00:00.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch 2025-04-12 16:51:53.000000000 +0300 @@ -0,0 +1,75 @@ +From e24ecac8065522917be689ecc498061bd1bb36c9 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Feb 2025 17:07:24 +0000 +Subject: gdatetime: Factor out some string pointer arithmetic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Makes the following code a little clearer, but doesn’t introduce any +functional changes. + +Signed-off-by: Philip Withnall +--- + glib/gdatetime.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index 72b8d04c6..2710e56fd 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -1355,6 +1355,7 @@ parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + gint i, offset_hours, offset_minutes; + gint offset_sign = 1; + GTimeZone *tz; ++ const char *tz_start; + + /* UTC uses Z suffix */ + if (length > 0 && text[length - 1] == 'Z') +@@ -1372,34 +1373,35 @@ parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + } + if (i < 0) + return NULL; ++ tz_start = text + i; + tz_length = length - i; + + /* +hh:mm or -hh:mm */ +- if (tz_length == 6 && text[i+3] == ':') ++ if (tz_length == 6 && tz_start[3] == ':') + { +- if (!get_iso8601_int (text + i + 1, 2, &offset_hours) || +- !get_iso8601_int (text + i + 4, 2, &offset_minutes)) ++ if (!get_iso8601_int (tz_start + 1, 2, &offset_hours) || ++ !get_iso8601_int (tz_start + 4, 2, &offset_minutes)) + return NULL; + } + /* +hhmm or -hhmm */ + else if (tz_length == 5) + { +- if (!get_iso8601_int (text + i + 1, 2, &offset_hours) || +- !get_iso8601_int (text + i + 3, 2, &offset_minutes)) ++ if (!get_iso8601_int (tz_start + 1, 2, &offset_hours) || ++ !get_iso8601_int (tz_start + 3, 2, &offset_minutes)) + return NULL; + } + /* +hh or -hh */ + else if (tz_length == 3) + { +- if (!get_iso8601_int (text + i + 1, 2, &offset_hours)) ++ if (!get_iso8601_int (tz_start + 1, 2, &offset_hours)) + return NULL; + offset_minutes = 0; + } + else + return NULL; + +- *tz_offset = i; +- tz = g_time_zone_new_identifier (text + i); ++ *tz_offset = tz_start - text; ++ tz = g_time_zone_new_identifier (tz_start); + + /* Double-check that the GTimeZone matches our interpretation of the timezone. + * This can fail because our interpretation is less strict than (for example) +-- +2.30.2 + diff -Nru glib2.0-2.74.6/debian/patches/0005-gdatetime-Factor-out-an-undersized-variable.patch glib2.0-2.74.6/debian/patches/0005-gdatetime-Factor-out-an-undersized-variable.patch --- glib2.0-2.74.6/debian/patches/0005-gdatetime-Factor-out-an-undersized-variable.patch 1970-01-01 02:00:00.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/0005-gdatetime-Factor-out-an-undersized-variable.patch 2025-04-12 16:51:53.000000000 +0300 @@ -0,0 +1,56 @@ +From df5cfea3236ec479807353563abe00ddaa7c9dd8 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Feb 2025 17:28:33 +0000 +Subject: gdatetime: Factor out an undersized variable + +For long input strings, it would have been possible for `i` to overflow. +Avoid that problem by using the `tz_length` instead, so that we count up +rather than down. + +This commit introduces no functional changes (outside of changing +undefined behaviour), and can be verified using the identity +`i === length - tz_length`. + +Signed-off-by: Philip Withnall +--- + glib/gdatetime.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index 2710e56fd..5f6b9f752 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -1352,7 +1352,7 @@ static GTimeZone * + parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + { + size_t tz_length; +- gint i, offset_hours, offset_minutes; ++ gint offset_hours, offset_minutes; + gint offset_sign = 1; + GTimeZone *tz; + const char *tz_start; +@@ -1365,16 +1365,15 @@ parse_iso8601_timezone (const gchar *text, gsize length, size_t *tz_offset) + } + + /* Look for '+' or '-' of offset */ +- for (i = length - 1; i >= 0; i--) +- if (text[i] == '+' || text[i] == '-') ++ for (tz_length = 1; tz_length <= length; tz_length++) ++ if (text[length - tz_length] == '+' || text[length - tz_length] == '-') + { +- offset_sign = text[i] == '-' ? -1 : 1; ++ offset_sign = text[length - tz_length] == '-' ? -1 : 1; + break; + } +- if (i < 0) ++ if (tz_length > length) + return NULL; +- tz_start = text + i; +- tz_length = length - i; ++ tz_start = text + length - tz_length; + + /* +hh:mm or -hh:mm */ + if (tz_length == 6 && tz_start[3] == ':') +-- +2.30.2 + diff -Nru glib2.0-2.74.6/debian/patches/series glib2.0-2.74.6/debian/patches/series --- glib2.0-2.74.6/debian/patches/series 2024-11-14 11:42:34.000000000 +0200 +++ glib2.0-2.74.6/debian/patches/series 2025-04-12 16:52:16.000000000 +0300 @@ -44,3 +44,8 @@ CVE-2024-34397/gdbusconnection-Allow-name-owners-to-have-the-syntax-of-a.patch gdbusmessage-Clean-the-cached-arg0-when-setting-the-messa.patch gsocks4aproxy-Fix-a-single-byte-buffer-overflow-in-connec.patch +0001-gdatetime-Fix-integer-overflow-when-parsing-very-lon.patch +0002-gdatetime-Fix-potential-integer-overflow-in-timezone.patch +0003-gdatetime-Track-timezone-length-as-an-unsigned-size_.patch +0004-gdatetime-Factor-out-some-string-pointer-arithmetic.patch +0005-gdatetime-Factor-out-an-undersized-variable.patch
Read more here: Source link