Files
buildroot/package/libglib2/0005-gvariant-parser-Convert-error-handling-code-to-use-s.patch
Peter Korsgaard 5c906d4a31 package/libglib2: backport security fixes for CVE-2025-14087
Fixes CVE-2025-14087: A flaw was found in GLib (Gnome Lib).  This
vulnerability allows a remote attacker to cause heap corruption, leading to
a denial of service or potential code execution via a buffer-underflow in
the GVariant parser when processing maliciously crafted input strings.

https://gitlab.gnome.org/GNOME/glib/-/issues/3834

The fixes were applied upstream as part of 2.86.3, so backport them for the
2.82.5 version currently used by Buildroot LTS.

Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
2026-07-02 21:55:12 +02:00

154 lines
4.7 KiB
Diff

From f856ca2b86dcbfd8983fed7b6e9b43cf3ae2a5ad Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Tue, 25 Nov 2025 19:25:58 +0000
Subject: [PATCH] gvariant-parser: Convert error handling code to use size_t
The error handling code allows for printing out the range of input bytes
related to a parsing error. This was previously done using `gint`, but
the input could be longer than `INT_MAX`, so it should really be done
using `size_t`.
Spotted while working on #3834.
CVE: CVE-2025-14087
Upstream: https://gitlab.gnome.org/GNOME/glib/-/commit/dd333a40aa95819720a01caf6de564cd8a4a6310
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
(cherry picked from commit dd333a40aa95819720a01caf6de564cd8a4a6310)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
glib/gvariant-parser.c | 36 +++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c
index 6d20db7ef..163e2b586 100644
--- a/glib/gvariant-parser.c
+++ b/glib/gvariant-parser.c
@@ -91,7 +91,9 @@ g_variant_parser_get_error_quark (void)
typedef struct
{
- gint start, end;
+ /* Offsets from the start of the input, in bytes. Can be equal when referring
+ * to a point rather than a range. The invariant `end >= start` always holds. */
+ size_t start, end;
} SourceRef;
G_GNUC_PRINTF(5, 0)
@@ -106,14 +108,16 @@ parser_set_error_va (GError **error,
GString *msg = g_string_new (NULL);
if (location->start == location->end)
- g_string_append_printf (msg, "%d", location->start);
+ g_string_append_printf (msg, "%" G_GSIZE_FORMAT, location->start);
else
- g_string_append_printf (msg, "%d-%d", location->start, location->end);
+ g_string_append_printf (msg, "%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
+ location->start, location->end);
if (other != NULL)
{
g_assert (other->start != other->end);
- g_string_append_printf (msg, ",%d-%d", other->start, other->end);
+ g_string_append_printf (msg, ",%" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
+ other->start, other->end);
}
g_string_append_c (msg, ':');
@@ -140,11 +144,15 @@ parser_set_error (GError **error,
typedef struct
{
+ /* We should always have the following ordering constraint:
+ * start <= this <= stream <= end
+ * Additionally, unless in an error or EOF state, `this < stream`.
+ */
const gchar *start;
const gchar *stream;
const gchar *end;
- const gchar *this;
+ const gchar *this; /* (nullable) */
} TokenStream;
@@ -175,7 +183,7 @@ token_stream_set_error (TokenStream *stream,
static gboolean
token_stream_prepare (TokenStream *stream)
{
- gint brackets = 0;
+ gssize brackets = 0;
const gchar *end;
if (stream->this != NULL)
@@ -405,7 +413,7 @@ static void
pattern_copy (gchar **out,
const gchar **in)
{
- gint brackets = 0;
+ gssize brackets = 0;
while (**in == 'a' || **in == 'm' || **in == 'M')
*(*out)++ = *(*in)++;
@@ -2743,7 +2751,7 @@ g_variant_builder_add_parsed (GVariantBuilder *builder,
static gboolean
parse_num (const gchar *num,
const gchar *limit,
- guint *result)
+ size_t *result)
{
gchar *endptr;
gint64 bignum;
@@ -2753,10 +2761,12 @@ parse_num (const gchar *num,
if (endptr != limit)
return FALSE;
+ /* The upper bound here is more restrictive than it technically needs to be,
+ * but should be enough for any practical situation: */
if (bignum < 0 || bignum > G_MAXINT)
return FALSE;
- *result = (guint) bignum;
+ *result = (size_t) bignum;
return TRUE;
}
@@ -2767,7 +2777,7 @@ add_last_line (GString *err,
{
const gchar *last_nl;
gchar *chomped;
- gint i;
+ size_t i;
/* This is an error at the end of input. If we have a file
* with newlines, that's probably the empty string after the
@@ -2912,7 +2922,7 @@ g_variant_parse_error_print_context (GError *error,
if (dash == NULL || colon < dash)
{
- guint point;
+ size_t point;
/* we have a single point */
if (!parse_num (error->message, colon, &point))
@@ -2930,7 +2940,7 @@ g_variant_parse_error_print_context (GError *error,
/* We have one or two ranges... */
if (comma && comma < colon)
{
- guint start1, end1, start2, end2;
+ size_t start1, end1, start2, end2;
const gchar *dash2;
/* Two ranges */
@@ -2946,7 +2956,7 @@ g_variant_parse_error_print_context (GError *error,
}
else
{
- guint start, end;
+ size_t start, end;
/* One range */
if (!parse_num (error->message, dash, &start) || !parse_num (dash + 1, colon, &end))
--
2.43.0