From patchwork Wed Dec 31 09:55:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Marko X-Patchwork-Id: 77820 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4F7AEE6421 for ; Wed, 31 Dec 2025 09:56:00 +0000 (UTC) Received: from mta-64-227.siemens.flowmailer.net (mta-64-227.siemens.flowmailer.net [185.136.64.227]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.82896.1767174951648502541 for ; Wed, 31 Dec 2025 01:55:51 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=peter.marko@siemens.com header.s=fm2 header.b=B9++bCYA; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.227, mailfrom: fm-256628-20251231095549b5a32263b600020765-ck6tsz@rts-flowmailer.siemens.com) Received: by mta-64-227.siemens.flowmailer.net with ESMTPSA id 20251231095549b5a32263b600020765 for ; Wed, 31 Dec 2025 10:55:50 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=peter.marko@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc; bh=dNlKbdCXbqewOYP9+iy4QuN0uo4+UWN3lDK7RQEGhIM=; b=B9++bCYAWW2GRh24iW+s2rvgWpjk3BWwGgGUakHgN315ToK0cbQB7JavfjcjjtKZOrupic Jyf6lRbaj616s/8EO2QaBnjR0Dd1QMVrZTakUX/zvX6JKoe6ajuD5rXph97pkzmciaufETAS eHmj16iWwRdDnOIU15Twmm/JLVvWsnIsuwzgSz/XadceVPQpksaI2U92MNShG6hk11ZFom2N rpROJ0+hV6Ynf8wNyHJz0YWagE59gLv2xw2fYvmtABskrX0YbuubtX0JfLmlQMocZm90FXf7 kebqzmYXHFZGVSklP9JtplPODy+puibwQg4pMlD2cploSCl4Ql6Hrc2A==; From: Peter Marko To: openembedded-core@lists.openembedded.org Cc: Peter Marko Subject: [OE-core][kirkstone][PATCH 1/3] glib-2.0: patch CVE-2025-13601 Date: Wed, 31 Dec 2025 10:55:42 +0100 Message-Id: <20251231095544.920217-1-peter.marko@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-256628:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 31 Dec 2025 09:56:00 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/228728 From: Peter Marko Pick commits from [1] per [2]. [1] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4914 [2] https://nvd.nist.gov/vuln/detail/CVE-2025-13601 Signed-off-by: Peter Marko --- .../glib-2.0/glib-2.0/CVE-2025-13601-01.patch | 125 +++++++++++++++++ .../glib-2.0/glib-2.0/CVE-2025-13601-02.patch | 128 ++++++++++++++++++ meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb | 2 + 3 files changed, 255 insertions(+) create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-01.patch create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-02.patch diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-01.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-01.patch new file mode 100644 index 00000000000..7046d2405e8 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-01.patch @@ -0,0 +1,125 @@ +From f28340ee62c655487972ad3c632d231ee098fb7f Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 13 Nov 2025 18:27:22 +0000 +Subject: [PATCH] gconvert: Error out if g_escape_uri_string() would overflow + +If the string to escape contains a very large number of unacceptable +characters (which would need escaping), the calculation of the length of +the escaped string could overflow, leading to a potential write off the +end of the newly allocated string. + +In addition to that, the number of unacceptable characters was counted +in a signed integer, which would overflow to become negative, making it +easier for an attacker to craft an input string which would cause an +out-of-bounds write. + +Fix that by validating the allocation length, and using an unsigned +integer to count the number of unacceptable characters. + +Spotted by treeplus. Thanks to the Sovereign Tech Resilience programme +from the Sovereign Tech Agency. ID: #YWH-PGM9867-134 + +Signed-off-by: Philip Withnall + +Fixes: #3827 + +CVE: CVE-2025-13601 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/f28340ee62c655487972ad3c632d231ee098fb7f] +Signed-off-by: Peter Marko +--- + glib/gconvert.c | 36 +++++++++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 11 deletions(-) + +diff --git a/glib/gconvert.c b/glib/gconvert.c +index b066dd5a8..a02d2ea73 100644 +--- a/glib/gconvert.c ++++ b/glib/gconvert.c +@@ -1425,8 +1425,9 @@ static const gchar hex[] = "0123456789ABCDEF"; + /* Note: This escape function works on file: URIs, but if you want to + * escape something else, please read RFC-2396 */ + static gchar * +-g_escape_uri_string (const gchar *string, +- UnsafeCharacterSet mask) ++g_escape_uri_string (const gchar *string, ++ UnsafeCharacterSet mask, ++ GError **error) + { + #define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask)) + +@@ -1434,7 +1435,7 @@ g_escape_uri_string (const gchar *string, + gchar *q; + gchar *result; + int c; +- gint unacceptable; ++ size_t unacceptable; + UnsafeCharacterSet use_mask; + + g_return_val_if_fail (mask == UNSAFE_ALL +@@ -1451,7 +1452,14 @@ g_escape_uri_string (const gchar *string, + if (!ACCEPTABLE (c)) + unacceptable++; + } +- ++ ++ if (unacceptable >= (G_MAXSIZE - (p - string)) / 2) ++ { ++ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, ++ _("The URI is too long")); ++ return NULL; ++ } ++ + result = g_malloc (p - string + unacceptable * 2 + 1); + + use_mask = mask; +@@ -1476,12 +1484,13 @@ g_escape_uri_string (const gchar *string, + + + static gchar * +-g_escape_file_uri (const gchar *hostname, +- const gchar *pathname) ++g_escape_file_uri (const gchar *hostname, ++ const gchar *pathname, ++ GError **error) + { + char *escaped_hostname = NULL; +- char *escaped_path; +- char *res; ++ char *escaped_path = NULL; ++ char *res = NULL; + + #ifdef G_OS_WIN32 + char *p, *backslash; +@@ -1502,10 +1511,14 @@ g_escape_file_uri (const gchar *hostname, + + if (hostname && *hostname != '\0') + { +- escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST); ++ escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST, error); ++ if (escaped_hostname == NULL) ++ goto out; + } + +- escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH); ++ escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH, error); ++ if (escaped_path == NULL) ++ goto out; + + res = g_strconcat ("file://", + (escaped_hostname) ? escaped_hostname : "", +@@ -1513,6 +1526,7 @@ g_escape_file_uri (const gchar *hostname, + escaped_path, + NULL); + ++out: + #ifdef G_OS_WIN32 + g_free ((char *) pathname); + #endif +@@ -1832,7 +1846,7 @@ g_filename_to_uri (const gchar *filename, + hostname = NULL; + #endif + +- escaped_uri = g_escape_file_uri (hostname, filename); ++ escaped_uri = g_escape_file_uri (hostname, filename, error); + + return escaped_uri; + } diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-02.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-02.patch new file mode 100644 index 00000000000..4be8d0d9478 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-13601-02.patch @@ -0,0 +1,128 @@ +From 7bd3fc372040cdf8eada7f65c32c30da52a7461d Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 13 Nov 2025 18:31:43 +0000 +Subject: [PATCH] fuzzing: Add fuzz tests for g_filename_{to,from}_uri() + +These functions could be called on untrusted input data, and since they +do URI escaping/unescaping, they have non-trivial string handling code. + +Signed-off-by: Philip Withnall + +See: #3827 + +CVE: CVE-2025-13601 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/7bd3fc372040cdf8eada7f65c32c30da52a7461d] +Signed-off-by: Peter Marko +--- + fuzzing/fuzz_filename_from_uri.c | 40 ++++++++++++++++++++++++++++++++ + fuzzing/fuzz_filename_to_uri.c | 40 ++++++++++++++++++++++++++++++++ + fuzzing/meson.build | 2 ++ + 3 files changed, 82 insertions(+) + create mode 100644 fuzzing/fuzz_filename_from_uri.c + create mode 100644 fuzzing/fuzz_filename_to_uri.c + +diff --git a/fuzzing/fuzz_filename_from_uri.c b/fuzzing/fuzz_filename_from_uri.c +new file mode 100644 +index 000000000..9b7a715f0 +--- /dev/null ++++ b/fuzzing/fuzz_filename_from_uri.c +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2025 GNOME Foundation, Inc. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "fuzz.h" ++ ++int ++LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) ++{ ++ unsigned char *nul_terminated_data = NULL; ++ char *filename = NULL; ++ GError *local_error = NULL; ++ ++ fuzz_set_logging_func (); ++ ++ /* ignore @size (g_filename_from_uri() doesn’t support it); ensure @data is nul-terminated */ ++ nul_terminated_data = (unsigned char *) g_strndup ((const char *) data, size); ++ filename = g_filename_from_uri ((const char *) nul_terminated_data, NULL, &local_error); ++ g_free (nul_terminated_data); ++ ++ g_free (filename); ++ g_clear_error (&local_error); ++ ++ return 0; ++} +diff --git a/fuzzing/fuzz_filename_to_uri.c b/fuzzing/fuzz_filename_to_uri.c +new file mode 100644 +index 000000000..acb319203 +--- /dev/null ++++ b/fuzzing/fuzz_filename_to_uri.c +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2025 GNOME Foundation, Inc. ++ * ++ * SPDX-License-Identifier: LGPL-2.1-or-later ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, see . ++ */ ++ ++#include "fuzz.h" ++ ++int ++LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) ++{ ++ unsigned char *nul_terminated_data = NULL; ++ char *uri = NULL; ++ GError *local_error = NULL; ++ ++ fuzz_set_logging_func (); ++ ++ /* ignore @size (g_filename_to_uri() doesn’t support it); ensure @data is nul-terminated */ ++ nul_terminated_data = (unsigned char *) g_strndup ((const char *) data, size); ++ uri = g_filename_to_uri ((const char *) nul_terminated_data, NULL, &local_error); ++ g_free (nul_terminated_data); ++ ++ g_free (uri); ++ g_clear_error (&local_error); ++ ++ return 0; ++} +diff --git a/fuzzing/meson.build b/fuzzing/meson.build +index addbe9071..05f936eeb 100644 +--- a/fuzzing/meson.build ++++ b/fuzzing/meson.build +@@ -4,6 +4,8 @@ fuzz_targets = [ + 'fuzz_date_parse', + 'fuzz_date_time_new_from_iso8601', + 'fuzz_dbus_message', ++ 'fuzz_filename_from_uri', ++ 'fuzz_filename_to_uri', + 'fuzz_inet_address_mask_new_from_string', + 'fuzz_inet_address_new_from_string', + 'fuzz_inet_socket_address_new_from_string', diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb index 7ba52b5c791..1c4c21614a2 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb @@ -64,6 +64,8 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ file://CVE-2025-4373-02.patch \ file://CVE-2025-7039-01.patch \ file://CVE-2025-7039-02.patch \ + file://CVE-2025-13601-01.patch \ + file://CVE-2025-13601-02.patch \ " SRC_URI:append:class-native = " file://relocate-modules.patch" From patchwork Wed Dec 31 09:55:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Marko X-Patchwork-Id: 77821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7373EE6420 for ; Wed, 31 Dec 2025 09:56:10 +0000 (UTC) Received: from mta-65-225.siemens.flowmailer.net (mta-65-225.siemens.flowmailer.net [185.136.65.225]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.82898.1767174961990586730 for ; Wed, 31 Dec 2025 01:56:02 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=peter.marko@siemens.com header.s=fm2 header.b=lTSJqTKV; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.65.225, mailfrom: fm-256628-202512310956005b306eb1eb000207e9-howewd@rts-flowmailer.siemens.com) Received: by mta-65-225.siemens.flowmailer.net with ESMTPSA id 202512310956005b306eb1eb000207e9 for ; Wed, 31 Dec 2025 10:56:00 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=peter.marko@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=1kcPIAVyLLeflxkZw4HBLGGsdTadB4fkl8/Jb+kXFAU=; b=lTSJqTKVdn7nQUOvrwfrl2LKiZXUtAQkpmusY0FLUONDI95IXAViScm0xgPfAQnP3WNfMe CFsHNJc7ZFVvIXG/lJ1/GFfg6GXGBkdKsf8IXVFY31tJIckEpyfZbz/t68mOXXr1pQDBWbWq oUnIX0YkaUOzAw69KbVPHU+K+W7KtOO+PPlbBSMB7JKNJCvw9+ecO3sGr5HdDfWxg16qZSZD eCHWpMNpzdUMvhBYO9B1/LCP/8USN9OFD0OJoVUQXQy1hPTbLDLUB5rNDJ5iiTqxvcAno3h1 +H8ygPh0PRXl7VvAORwCB91DOChwAG/5CiyG4FsRhImcuvxYOdRm977w==; From: Peter Marko To: openembedded-core@lists.openembedded.org Cc: Peter Marko Subject: [OE-core][kirkstone][PATCH 2/3] glib-2.0: patch CVE-2025-14087 Date: Wed, 31 Dec 2025 10:55:43 +0100 Message-Id: <20251231095544.920217-2-peter.marko@siemens.com> In-Reply-To: <20251231095544.920217-1-peter.marko@siemens.com> References: <20251231095544.920217-1-peter.marko@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-256628:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 31 Dec 2025 09:56:10 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/228729 From: Peter Marko Pick commits from [1] linked from [2]. [1] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4933 [2] https://gitlab.gnome.org/GNOME/glib/-/issues/3834 Signed-off-by: Peter Marko --- .../glib-2.0/glib-2.0/CVE-2025-14087-01.patch | 69 +++++ .../glib-2.0/glib-2.0/CVE-2025-14087-02.patch | 240 ++++++++++++++++++ .../glib-2.0/glib-2.0/CVE-2025-14087-03.patch | 150 +++++++++++ meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb | 3 + 4 files changed, 462 insertions(+) create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-01.patch create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-02.patch create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-03.patch diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-01.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-01.patch new file mode 100644 index 00000000000..ec7b1fecaaf --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-01.patch @@ -0,0 +1,69 @@ +From 31f82e22e21bae520b7228f7f57d357fb20df8a4 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Nov 2025 19:02:56 +0000 +Subject: [PATCH] gvariant-parser: Fix potential integer overflow parsing + (byte)strings + +The termination condition for parsing string and bytestring literals in +GVariant text format input was subject to an integer overflow for input +string (or bytestring) literals longer than `INT_MAX`. + +Fix that by counting as a `size_t` rather than as an `int`. The counter +can never correctly be negative. + +Spotted by treeplus. Thanks to the Sovereign Tech Resilience programme +from the Sovereign Tech Agency. ID: #YWH-PGM9867-145 + +Signed-off-by: Philip Withnall +Fixes: #3834 + +CVE: CVE-2025-14087 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/31f82e22e21bae520b7228f7f57d357fb20df8a4] +Signed-off-by: Peter Marko +--- + glib/gvariant-parser.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c +index 2f1d3db9f..2d6e9856f 100644 +--- a/glib/gvariant-parser.c ++++ b/glib/gvariant-parser.c +@@ -594,7 +594,7 @@ ast_resolve (AST *ast, + { + GVariant *value; + gchar *pattern; +- gint i, j = 0; ++ size_t i, j = 0; + + pattern = ast_get_pattern (ast, error); + +@@ -1555,9 +1555,9 @@ string_free (AST *ast) + * No leading/trailing space allowed. */ + static gboolean + unicode_unescape (const gchar *src, +- gint *src_ofs, ++ size_t *src_ofs, + gchar *dest, +- gint *dest_ofs, ++ size_t *dest_ofs, + gsize length, + SourceRef *ref, + GError **error) +@@ -1618,7 +1618,7 @@ string_parse (TokenStream *stream, + gsize length; + gchar quote; + gchar *str; +- gint i, j; ++ size_t i, j; + + token_stream_start_ref (stream, &ref); + token = token_stream_get (stream); +@@ -1748,7 +1748,7 @@ bytestring_parse (TokenStream *stream, + gsize length; + gchar quote; + gchar *str; +- gint i, j; ++ size_t i, j; + + token_stream_start_ref (stream, &ref); + token = token_stream_get (stream); diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-02.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-02.patch new file mode 100644 index 00000000000..595f9c1b935 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-02.patch @@ -0,0 +1,240 @@ +From ac9de0871281cf734f6e269988f90a2521582a08 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 25 Nov 2025 19:19:16 +0000 +Subject: [PATCH] gvariant-parser: Use size_t to count numbers of child + elements +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than using `gint`, which could overflow for arrays (or dicts, or +tuples) longer than `INT_MAX`. There may be other limits which prevent +parsed containers becoming that long, but we might as well make the type +system reflect the programmer’s intention as best it can anyway. + +For arrays and tuples this is straightforward. For dictionaries, it’s +slightly complicated by the fact that the code used +`dict->n_children == -1` to indicate that the `Dictionary` struct in +question actually represented a single freestanding dict entry. In +GVariant text format, that would be `{1, "one"}`. + +The implementation previously didn’t define the semantics of +`dict->n_children < -1`. + +Now, instead, change `Dictionary.n_children` to `size_t`, and define a +magic value `DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY` to indicate that +the `Dictionary` represents a single freestanding dict entry. + +This magic value is `SIZE_MAX`, and given that a dictionary entry takes +more than one byte to represent in GVariant text format, that means it’s +not possible to have that many entries in a parsed dictionary, so this +magic value won’t be hit by a normal dictionary. An assertion checks +this anyway. + +Spotted while working on #3834. + +Signed-off-by: Philip Withnall + +CVE: CVE-2025-14087 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/ac9de0871281cf734f6e269988f90a2521582a08] +Signed-off-by: Peter Marko +--- + glib/gvariant-parser.c | 58 ++++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 25 deletions(-) + +diff --git a/glib/gvariant-parser.c b/glib/gvariant-parser.c +index 2d6e9856f..519baa3f3 100644 +--- a/glib/gvariant-parser.c ++++ b/glib/gvariant-parser.c +@@ -647,9 +647,9 @@ static AST *parse (TokenStream *stream, + GError **error); + + static void +-ast_array_append (AST ***array, +- gint *n_items, +- AST *ast) ++ast_array_append (AST ***array, ++ size_t *n_items, ++ AST *ast) + { + if ((*n_items & (*n_items - 1)) == 0) + *array = g_renew (AST *, *array, *n_items ? 2 ** n_items : 1); +@@ -658,10 +658,10 @@ ast_array_append (AST ***array, + } + + static void +-ast_array_free (AST **array, +- gint n_items) ++ast_array_free (AST **array, ++ size_t n_items) + { +- gint i; ++ size_t i; + + for (i = 0; i < n_items; i++) + ast_free (array[i]); +@@ -670,11 +670,11 @@ ast_array_free (AST **array, + + static gchar * + ast_array_get_pattern (AST **array, +- gint n_items, ++ size_t n_items, + GError **error) + { + gchar *pattern; +- gint i; ++ size_t i; + + /* Find the pattern which applies to all children in the array, by l-folding a + * coalesce operation. +@@ -706,7 +706,7 @@ ast_array_get_pattern (AST **array, + * pair of values. + */ + { +- int j = 0; ++ size_t j = 0; + + while (TRUE) + { +@@ -891,7 +891,7 @@ typedef struct + AST ast; + + AST **children; +- gint n_children; ++ size_t n_children; + } Array; + + static gchar * +@@ -924,7 +924,7 @@ array_get_value (AST *ast, + Array *array = (Array *) ast; + const GVariantType *childtype; + GVariantBuilder builder; +- gint i; ++ size_t i; + + if (!g_variant_type_is_array (type)) + return ast_type_error (ast, type, error); +@@ -1010,7 +1010,7 @@ typedef struct + AST ast; + + AST **children; +- gint n_children; ++ size_t n_children; + } Tuple; + + static gchar * +@@ -1020,7 +1020,7 @@ tuple_get_pattern (AST *ast, + Tuple *tuple = (Tuple *) ast; + gchar *result = NULL; + gchar **parts; +- gint i; ++ size_t i; + + parts = g_new (gchar *, tuple->n_children + 4); + parts[tuple->n_children + 1] = (gchar *) ")"; +@@ -1050,7 +1050,7 @@ tuple_get_value (AST *ast, + Tuple *tuple = (Tuple *) ast; + const GVariantType *childtype; + GVariantBuilder builder; +- gint i; ++ size_t i; + + if (!g_variant_type_is_tuple (type)) + return ast_type_error (ast, type, error); +@@ -1242,9 +1242,16 @@ typedef struct + + AST **keys; + AST **values; +- gint n_children; ++ ++ /* Iff this is DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY then this struct ++ * represents a single freestanding dict entry (`{1, "one"}`) rather than a ++ * full dict. In the freestanding case, @keys and @values have exactly one ++ * member each. */ ++ size_t n_children; + } Dictionary; + ++#define DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY ((size_t) -1) ++ + static gchar * + dictionary_get_pattern (AST *ast, + GError **error) +@@ -1259,7 +1266,7 @@ dictionary_get_pattern (AST *ast, + return g_strdup ("Ma{**}"); + + key_pattern = ast_array_get_pattern (dict->keys, +- abs (dict->n_children), ++ (dict->n_children == DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY) ? 1 : dict->n_children, + error); + + if (key_pattern == NULL) +@@ -1290,7 +1297,7 @@ dictionary_get_pattern (AST *ast, + return NULL; + + result = g_strdup_printf ("M%s{%c%s}", +- dict->n_children > 0 ? "a" : "", ++ (dict->n_children > 0 && dict->n_children != DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY) ? "a" : "", + key_char, value_pattern); + g_free (value_pattern); + +@@ -1304,7 +1311,7 @@ dictionary_get_value (AST *ast, + { + Dictionary *dict = (Dictionary *) ast; + +- if (dict->n_children == -1) ++ if (dict->n_children == DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY) + { + const GVariantType *subtype; + GVariantBuilder builder; +@@ -1337,7 +1344,7 @@ dictionary_get_value (AST *ast, + { + const GVariantType *entry, *key, *val; + GVariantBuilder builder; +- gint i; ++ size_t i; + + if (!g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DICTIONARY)) + return ast_type_error (ast, type, error); +@@ -1378,12 +1385,12 @@ static void + dictionary_free (AST *ast) + { + Dictionary *dict = (Dictionary *) ast; +- gint n_children; ++ size_t n_children; + +- if (dict->n_children > -1) +- n_children = dict->n_children; +- else ++ if (dict->n_children == DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY) + n_children = 1; ++ else ++ n_children = dict->n_children; + + ast_array_free (dict->keys, n_children); + ast_array_free (dict->values, n_children); +@@ -1401,7 +1408,7 @@ dictionary_parse (TokenStream *stream, + maybe_wrapper, dictionary_get_value, + dictionary_free + }; +- gint n_keys, n_values; ++ size_t n_keys, n_values; + gboolean only_one; + Dictionary *dict; + AST *first; +@@ -1444,7 +1451,7 @@ dictionary_parse (TokenStream *stream, + goto error; + + g_assert (n_keys == 1 && n_values == 1); +- dict->n_children = -1; ++ dict->n_children = DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY; + + return (AST *) dict; + } +@@ -1477,6 +1484,7 @@ dictionary_parse (TokenStream *stream, + } + + g_assert (n_keys == n_values); ++ g_assert (n_keys != DICTIONARY_N_CHILDREN_FREESTANDING_ENTRY); + dict->n_children = n_keys; + + return (AST *) dict; diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-03.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-03.patch new file mode 100644 index 00000000000..4a474f39fcc --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14087-03.patch @@ -0,0 +1,150 @@ +From acaabfedff42e974334dd5368e6103d2845aaba6 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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. + +Signed-off-by: Philip Withnall + +CVE: CVE-2025-14087 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/acaabfedff42e974334dd5368e6103d2845aaba6] +Signed-off-by: Peter Marko +--- + 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 519baa3f3..1b1ddd654 100644 +--- a/glib/gvariant-parser.c ++++ b/glib/gvariant-parser.c +@@ -88,7 +88,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) +@@ -103,14 +105,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, ':'); + +@@ -137,11 +141,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; + + +@@ -172,7 +180,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) +@@ -402,7 +410,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)++; +@@ -2666,7 +2674,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; +@@ -2676,10 +2684,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; + } +@@ -2690,7 +2700,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 +@@ -2835,7 +2845,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)) +@@ -2853,7 +2863,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 */ +@@ -2869,7 +2879,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)) diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb index 1c4c21614a2..c5704a27bcc 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb @@ -66,6 +66,9 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ file://CVE-2025-7039-02.patch \ file://CVE-2025-13601-01.patch \ file://CVE-2025-13601-02.patch \ + file://CVE-2025-14087-01.patch \ + file://CVE-2025-14087-02.patch \ + file://CVE-2025-14087-03.patch \ " SRC_URI:append:class-native = " file://relocate-modules.patch" From patchwork Wed Dec 31 09:55:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Marko X-Patchwork-Id: 77822 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B50BAEE6423 for ; Wed, 31 Dec 2025 09:56:20 +0000 (UTC) Received: from mta-64-226.siemens.flowmailer.net (mta-64-226.siemens.flowmailer.net [185.136.64.226]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.82865.1767174972466217088 for ; Wed, 31 Dec 2025 01:56:12 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=peter.marko@siemens.com header.s=fm2 header.b=jPAdXxdq; spf=pass (domain: rts-flowmailer.siemens.com, ip: 185.136.64.226, mailfrom: fm-256628-20251231095610fa79df102a00020763-dhqkru@rts-flowmailer.siemens.com) Received: by mta-64-226.siemens.flowmailer.net with ESMTPSA id 20251231095610fa79df102a00020763 for ; Wed, 31 Dec 2025 10:56:10 +0100 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm2; d=siemens.com; i=peter.marko@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=kO9qe7sNN5aEkXKRxRBjIeexbns2NesU73P1tudEXlY=; b=jPAdXxdqe3/HR2nDF2MW+ZVIc6Pe3YDBKS3fZRk97lF2FhOcmyfKGaPHz0FxjGiiLJ6RyL kHQdK/hmanHMr9dfd9f9vPd0GqiI+r/1eRbwB8NHLY+2BAYcFtpkJGRuV9d4YPRn2VgkJuE3 11vZ23Xsz4AelpQbZLtBUJX0y44ATrlJy8BzmPVT9gssFQX4Wc63ULYBpyus4fIfUogDxEgH yGCBDToCB8jDD22pPD5bD9+w8nF6tuCEzPo4K7vdaDAWX4pOW0FSb077PlERJU/mPG4kpgXm 6eO0p2hn5zb3pDSB4vJQPwiR3WACP9/ebdqG5bILfHzT5eBbiHRxBkhA==; From: Peter Marko To: openembedded-core@lists.openembedded.org Cc: Peter Marko Subject: [OE-core][kirkstone][PATCH 3/3] glib-2.0: patch CVE-2025-14512 Date: Wed, 31 Dec 2025 10:55:44 +0100 Message-Id: <20251231095544.920217-3-peter.marko@siemens.com> In-Reply-To: <20251231095544.920217-1-peter.marko@siemens.com> References: <20251231095544.920217-1-peter.marko@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-256628:519-21489:flowmailer List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Wed, 31 Dec 2025 09:56:20 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/228730 From: Peter Marko Pick patch from [1] linked from [2]. [1] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4935 [2] https://gitlab.gnome.org/GNOME/glib/-/issues/3845 Signed-off-by: Peter Marko --- .../glib-2.0/glib-2.0/CVE-2025-14512.patch | 70 +++++++++++++++++++ meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb | 1 + 2 files changed, 71 insertions(+) create mode 100644 meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14512.patch diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14512.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14512.patch new file mode 100644 index 00000000000..fd3ba765b11 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2025-14512.patch @@ -0,0 +1,70 @@ +From 1909d8ea9297287f1ff6862968608dcf06e60523 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Thu, 4 Dec 2025 16:37:19 +0000 +Subject: [PATCH] gfileattribute: Fix integer overflow calculating escaping for + byte strings + +The number of invalid characters in the byte string (characters which +would have to be percent-encoded) was only stored in an `int`, which +gave the possibility of a long string largely full of invalid +characters overflowing this and allowing an attacker-controlled buffer +size to be allocated. + +This could be triggered by an attacker controlled file attribute (of +type `G_FILE_ATTRIBUTE_TYPE_BYTE_STRING`), such as +`G_FILE_ATTRIBUTE_THUMBNAIL_PATH` or `G_FILE_ATTRIBUTE_STANDARD_NAME`, +being read by user code. + +Spotted by Codean Labs. + +Signed-off-by: Philip Withnall + +Fixes: #3845 + +CVE: CVE-2025-14512 +Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/1909d8ea9297287f1ff6862968608dcf06e60523] +Signed-off-by: Peter Marko +--- + gio/gfileattribute.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/gio/gfileattribute.c b/gio/gfileattribute.c +index c6fde60fa..d3083e5bd 100644 +--- a/gio/gfileattribute.c ++++ b/gio/gfileattribute.c +@@ -20,6 +20,7 @@ + + #include "config.h" + ++#include + #include + + #include "gfileattribute.h" +@@ -271,11 +272,12 @@ valid_char (char c) + return c >= 32 && c <= 126 && c != '\\'; + } + ++/* Returns NULL on error */ + static char * + escape_byte_string (const char *str) + { + size_t i, len; +- int num_invalid; ++ size_t num_invalid; + char *escaped_val, *p; + unsigned char c; + const char hex_digits[] = "0123456789abcdef"; +@@ -293,7 +295,12 @@ escape_byte_string (const char *str) + return g_strdup (str); + else + { +- escaped_val = g_malloc (len + num_invalid*3 + 1); ++ /* Check for overflow. We want to check the inequality: ++ * !(len + num_invalid * 3 + 1 > SIZE_MAX) */ ++ if (num_invalid >= (SIZE_MAX - len) / 3) ++ return NULL; ++ ++ escaped_val = g_malloc (len + num_invalid * 3 + 1); + + p = escaped_val; + for (i = 0; i < len; i++) diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb index c5704a27bcc..50701be3d03 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.72.3.bb @@ -69,6 +69,7 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ file://CVE-2025-14087-01.patch \ file://CVE-2025-14087-02.patch \ file://CVE-2025-14087-03.patch \ + file://CVE-2025-14512.patch \ " SRC_URI:append:class-native = " file://relocate-modules.patch"