mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-09-26 03:50:44 -09:00
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>
154 lines
4.7 KiB
Diff
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
|
|
|