glib2/CVE-2026-58011.patch
RHEL Packaging Agent 783a9d08b9 Fix CVE-2026-58011: range validation in g_date_time_add_full()
Backport upstream fix for CVE-2026-58011 from MR !5131.
The patch includes two cherry-picked commits: a preparatory
refactoring introducing MIN_DAYS/MAX_DAYS constants, and the
actual fix adding bounds validation to g_date_time_add_full()
to prevent creation of invalid GDateTime objects. Test cases
for out-of-range inputs are also included.

CVE: CVE-2026-58011
Upstream patches:
 - https://gitlab.gnome.org/GNOME/glib/-/merge_requests/5131.patch
Resolves: RHEL-212183

This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.

Assisted-by: Ymir
2026-08-20 21:10:08 +00: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 f01b930221f51b06c8b63e714e6c444737c64fb3 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 7a214bb7b06cb9352f378b63d3bfd319b4626eda 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