glib2/CVE-2026-58010.patch
RHEL Packaging Agent 21e042597f Fix CVE-2026-58010: off-by-one in GVariant tuple offset checking
Add patch for CVE-2026-58010 which fixes an off-by-one error
in the GVariant tuple serialiser's normal form checking code.
The bug allowed a single byte out-of-bounds read when verifying
padding bytes in a short (non-normal) tuple. The patch changes
the offset comparison from `>` to `>=` in
gvs_tuple_is_normal() and adds a regression test. An additional
fix includes `<stdint.h>` in the test file so that the new test
using `uint8_t` compiles correctly against the older glib 2.80.4
codebase.

CVE: CVE-2026-58010
Upstream patches:
 - 8338414f65.patch
Resolves: RHEL-212160

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

129 lines
4.6 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 9aeaf880a1434139accc85337dac6e55c40188e0 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Sun, 29 Mar 2026 19:10:41 +0100
Subject: [PATCH 1/2] gvariant: Fix an off-by-one error in an offset comparison
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This allows a single byte out-of-bounds read off the end of the
(potentially untrusted) byte array backing a `GVariant` when its
being checked for normal form.
I cant see how this could practically be exploited, but its certainly
a security bug as the `GVariant` normal form checking code is supposed
to be robust to malicious inputs.
Spotted by linhlhq as #YWH-PGM9867-190, and fix and reproducer provided
by them too, thanks. Confirmed and turned into a unit test by me.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3915
---
glib/gvariant-serialiser.c | 2 +-
glib/tests/gvariant.c | 48 ++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 9a2975b33..85f28cdce 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1248,7 +1248,7 @@ gvs_tuple_is_normal (GVariantSerialised value)
while (offset & alignment)
{
- if (offset > value.size || value.data[offset] != '\0')
+ if (offset >= value.size || value.data[offset] != '\0')
return FALSE;
offset++;
}
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index c24cd2f3e..0d59779ed 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -5646,6 +5646,52 @@ test_normal_checking_tuple_offsets5 (void)
g_variant_unref (variant);
}
+/* This is a regression test that looping over the padding bytes in a short
+ * (non-normal) tuple doesnt overflow the input data.
+ *
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/3915 */
+static void
+test_normal_checking_tuple_offsets6 (void)
+{
+ /*
+ * Type: (ynqiuxthdsog) — 12 members, first member 'y' (byte) has
+ * alignment 0, second 'n' (int16) has alignment 1.
+ * With 1 byte of data (0x28), after reading the first byte member,
+ * offset=1, alignment check for 'n' requires offset to be even,
+ * so the while loop checks value.data[1] — but size is only 1.
+ *
+ * Use heap allocation via GBytes so ASan reports heap-buffer-overflow.
+ */
+ uint8_t *heap_data = NULL;
+ GBytes *bytes = NULL;
+ const GVariantType *data_type = G_VARIANT_TYPE ("(ynqiuxthdsog)");
+ GVariant *variant = NULL;
+ GVariant *normal_variant = NULL;
+ GVariant *expected = NULL;
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3915");
+
+ heap_data = g_malloc (1);
+ heap_data[0] = 0x28;
+ bytes = g_bytes_new_take (heap_data, 1);
+
+ variant = g_variant_new_from_bytes (data_type, bytes, FALSE);
+ g_assert_nonnull (variant);
+
+ g_assert_false (g_variant_is_normal_form (variant));
+
+ normal_variant = g_variant_get_normal_form (variant);
+ g_assert_nonnull (normal_variant);
+
+ expected = g_variant_new_parsed ("(byte 0x28, int16 0, uint16 0, 0, uint32 0, int64 0, uint64 0, handle 0, 0.0, '', objectpath '/', signature '')");
+ g_assert_cmpvariant (expected, variant);
+ g_assert_cmpvariant (expected, normal_variant);
+
+ g_variant_unref (expected);
+ g_variant_unref (normal_variant);
+ g_variant_unref (variant);
+}
+
/* Test that an otherwise-valid serialised GVariant is considered non-normal if
* its offset table entries are too wide.
*
@@ -5899,6 +5945,8 @@ main (int argc, char **argv)
test_normal_checking_tuple_offsets4);
g_test_add_func ("/gvariant/normal-checking/tuple-offsets5",
test_normal_checking_tuple_offsets5);
+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets6",
+ test_normal_checking_tuple_offsets6);
g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized",
test_normal_checking_tuple_offsets_minimal_sized);
g_test_add_func ("/gvariant/normal-checking/empty-object-path",
From 10b4d8d5679f49dfc68bb6b24656b18c7e8c588e Mon Sep 17 00:00:00 2001
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
Date: Thu, 20 Aug 2026 20:16:27 +0000
Subject: [PATCH 2/2] Include stdint.h for uint8_t in gvariant test
---
glib/tests/gvariant.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 0d59779ed..9f5b2d582 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -18,6 +18,7 @@
#include "config.h"
#include <glib/gvariant-internal.h>
+#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>