Files
poky/meta/recipes-core/glib-2.0/glib-2.0/CVE-2026-58013.patch
Deepak Rathore 6ae62b54aa glib-2.0: fix CVE-2026-58013
This patch applies the upstream 2.88.1 backport for
CVE-2026-58013. The upstream fix commit is referenced in [1],
and the public CVE advisory is referenced in [2].

[1] 6a2583dec3
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-58013

(From OE-Core rev: cb2fd8601b4243183d5e219b901439da3f2d41c8)

Signed-off-by: Deepak Rathore <deeratho@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
2026-07-30 13:21:16 +01:00

141 lines
4.9 KiB
Diff
Raw 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 cb9d97e1b261d75eb8ea255e0a9f3e846d547af7 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
Date: Tue, 28 Apr 2026 16:45:14 +0100
Subject: [PATCH] giochannel: Fix memcmp() off the end of the buffer with long
terminators
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the line terminator is longer than a single byte, and the current
line extends to the end of the buffer, and the buffer (which is a
`GString`) is near a power of two in length (as that’s how `GString`s
are allocated) it’s possible for the `memcmp()` which checks the
terminator to read off the end of the string buffer.
Fix that by checking the terminator length against the last character
before calling `memcmp()`. Add a unit test.
Spotted by linhlhq as #YWH-PGM9867-199. The fix is theirs (validated by
me), and the unit test is adapted from their proof of concept.
Fixes: #3925
CVE: CVE-2026-58013
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/6a2583dec39bfe05553b16d9b7419d6c2a257244]
Backport Changes:
- Added the <stdint.h> include for the regression test because these target
branches do not otherwise expose uint8_t in glib/tests/io-channel.c.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
(cherry picked from commit 6a2583dec39bfe05553b16d9b7419d6c2a257244)
Signed-off-by: Deepak Rathore <deeratho@cisco.com>
---
glib/giochannel.c | 3 ++-
glib/tests/io-channel.c | 61 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/glib/giochannel.c b/glib/giochannel.c
index 7572c47a2..8d867d0fb 100644
--- a/glib/giochannel.c
+++ b/glib/giochannel.c
@@ -1833,7 +1833,8 @@ read_again:
{
if (channel->line_term)
{
- if (memcmp (channel->line_term, nextchar, line_term_len) == 0)
+ if ((size_t) (lastchar - nextchar) >= line_term_len &&
+ memcmp (channel->line_term, nextchar, line_term_len) == 0)
{
line_length = nextchar - use_buf->str;
got_term_len = line_term_len;
diff --git a/glib/tests/io-channel.c b/glib/tests/io-channel.c
index c5dd01d04..cf81a9f6b 100644
--- a/glib/tests/io-channel.c
+++ b/glib/tests/io-channel.c
@@ -29,6 +29,7 @@
#include <glib.h>
#include <glib/gstdio.h>
+#include <stdint.h>
static void
test_small_writes (void)
@@ -216,6 +217,65 @@ test_read_line_embedded_nuls (void)
g_free (filename);
}
+static void
+test_read_line_long_terminator (void)
+{
+ uint8_t *test_data = NULL;
+ size_t test_data_len = 0;
+ int fd;
+ char *filename = NULL;
+ GIOChannel *channel = NULL;
+ GError *local_error = NULL;
+ char *line = NULL;
+ size_t line_length, terminator_pos;
+ const char *line_term;
+ int line_term_length;
+ GIOStatus status;
+
+ g_test_summary ("Test that reading a line when using a long terminator doesn’t over-read the buffer.");
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/work_items/3925");
+
+ /* Write out a temporary file containing 2047 bytes. This is enough to make it
+ * near the length of the GString buffer when read back in. */
+ fd = g_file_open_tmp ("glib-test-io-channel-XXXXXX", &filename, &local_error);
+ g_assert_no_error (local_error);
+ g_close (g_steal_fd (&fd), NULL);
+
+ test_data_len = 2047;
+ test_data = g_malloc (test_data_len);
+ memset (test_data, 'M', test_data_len);
+ g_file_set_contents (filename, (const gchar *) test_data, test_data_len, &local_error);
+ g_assert_no_error (local_error);
+
+ /* Create the channel. */
+ channel = g_io_channel_new_file (filename, "r", &local_error);
+ g_assert_no_error (local_error);
+
+ /* Use a long line terminator so it could potentially over-read the end of the buffer. */
+ g_io_channel_set_line_term (channel, "DEADBEEF", 8);
+
+ line_term = g_io_channel_get_line_term (channel, &line_term_length);
+ g_assert_cmpstr (line_term, ==, "DEADBEEF");
+ g_assert_cmpint (line_term_length, ==, 8);
+
+ g_io_channel_set_encoding (channel, "UTF-8", &local_error);
+ g_assert_no_error (local_error);
+
+ status = g_io_channel_read_line (channel, &line, &line_length,
+ &terminator_pos, &local_error);
+ g_assert_no_error (local_error);
+ g_assert_cmpint (status, ==, G_IO_STATUS_NORMAL);
+ g_assert_cmpuint (line_length, ==, 2047);
+ g_assert_cmpuint (terminator_pos, ==, 2047);
+ g_assert_cmpmem (line, line_length, test_data, test_data_len);
+
+ g_free (line);
+ g_io_channel_unref (channel);
+ g_free (test_data);
+ g_unlink (filename);
+ g_free (filename);
+}
+
int
main (int argc,
char *argv[])
@@ -224,6 +283,7 @@ main (int argc,
g_test_add_func ("/io-channel/read-write", test_read_write);
g_test_add_func ("/io-channel/read-line/embedded-nuls", test_read_line_embedded_nuls);
+ g_test_add_func ("/io-channel/read-line/long-terminator", test_read_line_long_terminator);
return g_test_run ();
}
--
2.35.6