diff mbox series

[wrynose,4/6] glib-2.0: Fix CVE-2026-58013

Message ID 20260715172142.1146263-4-deeratho@cisco.com
State New
Headers show
Series [wrynose,1/6] glib-2.0: Fix CVE-2026-58010 | expand

Commit Message

From: Deepak Rathore <deeratho@cisco.com>

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] https://gitlab.gnome.org/GNOME/glib/-/commit/6a2583dec39bfe05553b16d9b7419d6c2a257244
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-58013

Signed-off-by: Deepak Rathore <deeratho@cisco.com>
---
 .../glib-2.0/files/CVE-2026-58013.patch       | 140 ++++++++++++++++++
 meta/recipes-core/glib-2.0/glib.inc           |   1 +
 2 files changed, 141 insertions(+)
 create mode 100644 meta/recipes-core/glib-2.0/files/CVE-2026-58013.patch
diff mbox series

Patch

diff --git a/meta/recipes-core/glib-2.0/files/CVE-2026-58013.patch b/meta/recipes-core/glib-2.0/files/CVE-2026-58013.patch
new file mode 100644
index 0000000000..5677c91e09
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/files/CVE-2026-58013.patch
@@ -0,0 +1,140 @@ 
+From 6ced6ddb7c85bd7b6bd614835c030983078662d6 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 e54aea256..640f698cb 100644
+--- a/glib/giochannel.c
++++ b/glib/giochannel.c
+@@ -1828,7 +1828,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 cab486932..3ff5d38e3 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)
+@@ -228,6 +229,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[])
+@@ -236,6 +295,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
diff --git a/meta/recipes-core/glib-2.0/glib.inc b/meta/recipes-core/glib-2.0/glib.inc
index 767f63d6d9..2da58cad2f 100644
--- a/meta/recipes-core/glib-2.0/glib.inc
+++ b/meta/recipes-core/glib-2.0/glib.inc
@@ -236,6 +236,7 @@  SRC_URI += "\
            file://CVE-2026-58010.patch \
            file://CVE-2026-58011.patch \
            file://CVE-2026-58012.patch \
+           file://CVE-2026-58013.patch \
            "
 SRC_URI:append:class-native = " file://relocate-modules.patch \
                                 file://0001-meson.build-do-not-enable-pidfd-features-on-native-g.patch \