glib2/CVE-2026-58011.patch
2026-08-19 13:30:56 -04:00

123 lines
4.2 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From b1410fefcb0f478eef003de6f62c5308a0c37847 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Sun, 29 Mar 2026 23:19:47 +0100
Subject: [PATCH 1/2] gdatetime: Factor out a couple of magic constants
This introduces no functional changes, it just makes the code a little
clearer.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
---
glib/gdatetime.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index b5372d834..d2a46eb80 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -103,7 +103,7 @@ struct _GDateTime
gint interval;
/* 1 is 0001-01-01 in Proleptic Gregorian */
- gint32 days;
+ gint32 days; /* in range [MIN_DAYS, MAX_DAYS] */
gint ref_count; /* (atomic) */
};
@@ -145,6 +145,9 @@ struct _GDateTime
#define JULIAN_YEAR(d) ((d)->julian / 365.25)
#define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695))
+#define MIN_DAYS 1 /* the days count for 0001-01-01 in Proleptic Gregorian */
+#define MAX_DAYS 3652059 /* the days count for 9999-12-31 in Proleptic Gregorian */
+
static const guint16 days_in_months[2][13] =
{
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
@@ -779,7 +782,7 @@ g_date_time_from_instant (GTimeZone *tz,
datetime->days = instant / USEC_PER_DAY;
datetime->usec = instant % USEC_PER_DAY;
- if (datetime->days < 1 || 3652059 < datetime->days)
+ if (datetime->days < MIN_DAYS || datetime->days > MAX_DAYS)
{
g_date_time_unref (datetime);
datetime = NULL;
@@ -815,7 +818,7 @@ g_date_time_deal_with_date_change (GDateTime *datetime)
gint64 full_time;
gint64 usec;
- if (datetime->days < 1 || datetime->days > 3652059)
+ if (datetime->days < MIN_DAYS || datetime->days > MAX_DAYS)
return FALSE;
was_dst = g_time_zone_is_dst (datetime->tz, datetime->interval);
From 1fa222226d7e1737acd463b38ebd45759953de39 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Sun, 29 Mar 2026 23:46:17 +0100
Subject: [PATCH 2/2] gdatetime: Add missing range validation to
g_date_time_add_full()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Otherwise its possible to create a non-`NULL` but invalid `GDateTime`,
which breaks all kinds of internal assumptions.
Spotted by linhlhq as #YWH-PGM9867-191. Thanks to them for providing a
suggested fix and a test case, which I have adapted and validated.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3917
---
glib/gdatetime.c | 4 +++-
glib/tests/gdatetime.c | 18 ++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index d2a46eb80..e1bfd9e1c 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -2074,7 +2074,9 @@ g_date_time_add_full (GDateTime *datetime,
new->days = full_time / USEC_PER_DAY;
new->usec = full_time % USEC_PER_DAY;
- /* XXX validate */
+ /* Validate its still in the range 0001-01-01 to 9999-12-31 */
+ if (new->days < MIN_DAYS || new->days > MAX_DAYS)
+ g_clear_pointer (&new, g_date_time_unref);
return new;
}
diff --git a/glib/tests/gdatetime.c b/glib/tests/gdatetime.c
index 9e1acd097..bca5c93a4 100644
--- a/glib/tests/gdatetime.c
+++ b/glib/tests/gdatetime.c
@@ -1124,6 +1124,24 @@ test_GDateTime_add_full (void)
TEST_ADD_FULL (2010, 8, 25, 22, 45, 0,
0, 1, 6, 1, 25, 0,
2010, 10, 2, 0, 10, 0);
+
+#define TEST_ADD_FULL_ERROR(y,m,d,h,mi,s,ay,am,ad,ah,ami,as) G_STMT_START { \
+ GDateTime *dt; \
+ dt = g_date_time_new_utc (y, m, d, h, mi, s); \
+ g_assert_null (g_date_time_add_full (dt, ay, am, ad, ah, ami, as)); \
+ g_date_time_unref (dt); \
+} G_STMT_END
+
+ TEST_ADD_FULL_ERROR ( 1, 12, 1, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0);
+ TEST_ADD_FULL_ERROR ( 1, 12, 1, 0, 0, 0,
+ 10000, 0, 0, 0, 0, 0);
+ TEST_ADD_FULL_ERROR ( 9999, 12, 1, 0, 0, 0,
+ -10000, 0, 0, 0, 0, 0);
+ TEST_ADD_FULL_ERROR ( 1, 12, 1, 0, 0, 0,
+ 0, 0, 3660001, 0, 0, 0);
+ TEST_ADD_FULL_ERROR ( 9999, 12, 1, 0, 0, 0,
+ 0, 0, -3660001, 0, 0, 0);
}
static void