Fix CVE-2026-58010: off-by-one in GVariant tuple offset checking

Backport fix for CVE-2026-58010 from upstream commit
8338414f6560. The patch fixes an off-by-one error in
gvs_tuple_is_normal() in glib/gvariant-serialiser.c, changing
`offset > value.size` to `offset >= value.size`, preventing a
single byte out-of-bounds read when checking a GVariant for
normal form. Includes a regression test adapted for the
glib2 2.56.4 API.

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

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

Assisted-by: Ymir
This commit is contained in:
RHEL Packaging Agent 2026-07-30 12:29:14 +00:00 committed by Michael Catanzaro
parent ebe9cedbc9
commit ad9522f451
2 changed files with 106 additions and 1 deletions

99
CVE-2026-58010.patch Normal file
View File

@ -0,0 +1,99 @@
From 1e659071a5138209dfefc647eebccbca43250434 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Sun, 29 Mar 2026 19:10:41 +0100
Subject: [PATCH] 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 | 41 ++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index c6e400b53..9e862e50b 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1078,7 +1078,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 c4a996c1f..4d3186e46 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4842,6 +4842,45 @@ test_normal_checking_tuple_offsets (void)
g_variant_unref (variant);
}
+/* This is a regression test that looping over the padding bytes in a short
+ * (non-normal) tuple doesn't 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.
+ */
+ guint8 *heap_data = NULL;
+ GBytes *bytes = NULL;
+ const GVariantType *data_type = G_VARIANT_TYPE ("(ynqiuxthdsog)");
+ GVariant *variant = NULL;
+ GVariant *normal_variant = NULL;
+
+ 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);
+
+ g_bytes_unref (bytes);
+ g_variant_unref (normal_variant);
+ g_variant_unref (variant);
+}
+
/* Test that an empty object path is normalised successfully to the base object
* path, /. */
static void
@@ -4941,6 +4980,8 @@ main (int argc, char **argv)
test_normal_checking_array_offsets);
g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
test_normal_checking_tuple_offsets);
+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets6",
+ test_normal_checking_tuple_offsets6);
g_test_add_func ("/gvariant/normal-checking/empty-object-path",
test_normal_checking_empty_object_path);

View File

@ -5,7 +5,7 @@
Name: glib2
Version: 2.56.4
Release: 175%{?dist}
Release: 176%{?dist}
Summary: A library of handy utility functions
License: LGPLv2+
@ -187,6 +187,9 @@ Patch40: CVE-2026-58012.patch
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/5131
Patch41: CVE-2026-58011.patch
# https://gitlab.gnome.org/GNOME/glib/-/commit/8338414f6560216efe67d3cbf549e32f8630252a
Patch42: CVE-2026-58010.patch
%description
GLib is the low-level core library that forms the basis for projects
such as GTK+ and GNOME. It provides data structure handling for C,
@ -387,6 +390,9 @@ make %{?_smp_mflags} check
%{_datadir}/installed-tests
%changelog
* Thu Jul 30 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.56.4-176
- Fix CVE-2026-58010: off-by-one in GVariant tuple offset checking
* Mon Jul 20 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 2.56.4-175
- Fix CVE-2026-58011: range validation in g_date_time_add_full()
- Resolves: RHEL-212187