public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
To: git-commits@fedoraproject.org
Subject: [rpms/glib2] cve-2026-58016-f44: Drop ifuncs to unbreak qemu-user-static binaries
Date: Tue, 11 Aug 2026 10:38:25 GMT	[thread overview]
Message-ID: <178644470598.1.6688365296865117533.rpms-glib2-7b0d00dfe8a9@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : rpms/glib2
            Branch : cve-2026-58016-f44
            Commit : 7b0d00dfe8a96fbe6fa5bff8eda4b9bc918f9d03
            Author : Daniel P. Berrangé <berrange@redhat.com>
            Date   : 2024-12-06T18:12:17+00:00
            Stats  : +238/-0 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/glib2/c/7b0d00dfe8a96fbe6fa5bff8eda4b9bc918f9d03?branch=cve-2026-58016-f44

            Log:
            Drop ifuncs to unbreak qemu-user-static binaries

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2330793
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

---
diff --git a/0001-gutf8-Drop-ifunc-code-and-always-call-strlen-when-va.patch b/0001-gutf8-Drop-ifunc-code-and-always-call-strlen-when-va.patch
new file mode 100644
index 0000000..a2ad4b3
--- /dev/null
+++ b/0001-gutf8-Drop-ifunc-code-and-always-call-strlen-when-va.patch
@@ -0,0 +1,235 @@
+From 9a67e20d3cc1258ae10be7a2f9cf89ddd9aba025 Mon Sep 17 00:00:00 2001
+From: Philip Withnall <pwithnall@gnome.org>
+Date: Tue, 19 Nov 2024 13:49:34 +0000
+Subject: [PATCH] gutf8: Drop ifunc code and always call strlen() when
+ validating UTF-8
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes a heap buffer overflow read in `g_utf8_validate()` and
+`g_str_is_ascii()`, at the cost of always calling `strlen()` on the
+input string if its length isn’t known already.
+
+The overflow read was not a security vulnerability, but getting valgrind
+and asan to understand that, across all platforms and build
+configurations, doesn’t seem to be possible with the resources available
+to us. In particular, the `ifunc` approach doesn’t work on muslc, and
+doesn’t work when statically linked.
+
+The UTF-8 validation code should still be faster than the old approach
+(GLib 2.82 and older), as `strlen()` is SIMD-accelerated in glibc, and
+UTF-8 validation is SIMD accelerated in GLib. The combination of the two
+should still be faster than the bytewise read loop we used to have.
+
+Unfortunately, correctness and testability have to be prioritised over
+absolute performance.
+
+Signed-off-by: Philip Withnall <pwithnall@gnome.org>
+
+Fixes: #3493
+Fixes: #3511
+Fixes: #3526
+---
+ glib/gutf8.c | 133 ++++-----------------------------------------------
+ 1 file changed, 8 insertions(+), 125 deletions(-)
+
+diff --git a/glib/gutf8.c b/glib/gutf8.c
+index bca3358c2..95c683b5c 100644
+--- a/glib/gutf8.c
++++ b/glib/gutf8.c
+@@ -42,10 +42,6 @@
+ #include "glibintl.h"
+ #include "gvalgrind.h"
+ 
+-#if g_macro__has_attribute(ifunc) && !defined(G_OS_WIN32)
+-#define HAVE_WORKING_IFUNC_ATTRIBUTE 1
+-#endif
+-
+ #define UTF8_COMPUTE(Char, Mask, Len)					      \
+   if (Char < 128)							      \
+     {									      \
+@@ -1642,7 +1638,7 @@ utf8_verify_ascii (const char **strp,
+                    gsize       *lenp)
+ {
+   const char *str = *strp;
+-  gsize len = lenp ? *lenp : (gsize)-1;
++  gsize len = lenp ? *lenp : strlen (str);
+ 
+   while (len > 0 && load_u8 (str, 0) < 128)
+     {
+@@ -1691,7 +1687,7 @@ utf8_verify (const char **strp,
+              gsize       *lenp)
+ {
+   const char *str = *strp;
+-  gsize len = lenp ? *lenp : (gsize)-1;
++  gsize len = lenp ? *lenp : strlen (str);
+ 
+   /* See Unicode 10.0.0, Chapter 3, Section D92 */
+ 
+@@ -1829,77 +1825,6 @@ out:
+     *lenp = len;
+ }
+ 
+-static gboolean
+-g_utf8_validate_native (const char  *str,
+-                        gssize       max_len,
+-                        const char **end)
+-{
+-  if (max_len >= 0)
+-    return g_utf8_validate_len (str, max_len, end);
+-
+-  utf8_verify (&str, NULL);
+-
+-  if (end != NULL)
+-    *end = str;
+-
+-  return *str == 0;
+-}
+-
+-#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
+-/* The fast implementation of UTF-8 validation in `utf8_verify()` technically
+- * uses undefined behaviour when the string length is not provided (i.e. when
+- * it’s looking for a trailing nul terminator): when doing word-sized reads of
+- * the string, it can read up to the word size (minus one byte) beyond the end
+- * of the string in order to find the nul terminator.
+- *
+- * While this is guaranteed to not cause a page fault (at worst, the nul
+- * terminator could be in the final word of the page, and the code won’t read
+- * any further than that), it is still technically undefined behaviour in C,
+- * because we’re reading off the end of an array.
+- *
+- * We don’t *think* this can cause any bugs due to compiler optimisations,
+- * because glibc does exactly the same thing in its string handling code, and
+- * that code has been extensively tested. For example:
+- * https://github.com/bminor/glibc/blob/2c1903cbbac0022153a67776f474c221250ad6ed/string/strchrnul.c
+- *
+- * However, both valgrind and asan warn about the read beyond the end of the
+- * array (a ‘heap buffer overflow read’). They’re right to do this (they can’t
+- * know the read is bounded to the word size minus one, and guaranteed to not
+- * cross a page boundary), but it’s annoying for any application which calls
+- * `g_utf8_validate()`.
+- *
+- * Use an [indirect function (`ifunc`)](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-ifunc-function-attribute)
+- * to use a fallback implementation of `g_utf8_validate()` when running under
+- * valgrind. This is resolved at load time using `resolve_g_utf8_validate()`.
+- *
+- * Similarly, mark the real implementation so that it’s not instrumented by asan
+- * using `no_sanitize_address`.
+- */
+-static gboolean
+-g_utf8_validate_valgrind (const char  *str,
+-                          gssize       max_len,
+-                          const char **end)
+-{
+-  if (max_len < 0)
+-    max_len = strlen (str);
+-
+-  return g_utf8_validate_len (str, max_len, end);
+-}
+-
+-typedef gboolean (*GUtf8ValidateFunc) (const char  *str,
+-                                       gssize       max_len,
+-                                       const char **end);
+-
+-static GUtf8ValidateFunc
+-resolve_g_utf8_validate (void)
+-{
+-  if (RUNNING_ON_VALGRIND)
+-    return g_utf8_validate_valgrind;
+-  else
+-    return g_utf8_validate_native;
+-}
+-#endif  /* HAVE_WORKING_IFUNC_ATTRIBUTE */
+-
+ /**
+  * g_utf8_validate:
+  * @str: (array length=max_len) (element-type guint8): a pointer to character data
+@@ -1926,20 +1851,15 @@ resolve_g_utf8_validate (void)
+  * 
+  * Returns: `TRUE` if the text was valid UTF-8
+  */
+-#if g_macro__has_attribute(no_sanitize_address)
+-  __attribute__((no_sanitize_address))
+-#endif
+ gboolean
+ g_utf8_validate (const char   *str,
+                  gssize        max_len,
+                  const gchar **end)
+-#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
+-  __attribute__((ifunc ("resolve_g_utf8_validate")));
+-#else
+ {
+-  return g_utf8_validate_native (str, max_len, end);
++  size_t max_len_unsigned = (max_len >= 0) ? (size_t) max_len : strlen (str);
++
++  return g_utf8_validate_len (str, max_len_unsigned, end);
+ }
+-#endif
+ 
+ /**
+  * g_utf8_validate_len:
+@@ -1969,38 +1889,6 @@ g_utf8_validate_len (const char   *str,
+   return max_len == 0;
+ }
+ 
+-static gboolean
+-g_str_is_ascii_native (const char *str)
+-{
+-  utf8_verify_ascii (&str, NULL);
+-
+-  return *str == 0;
+-}
+-
+-#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
+-/* See above comment about `ifunc` use for g_utf8_validate(). */
+-static gboolean
+-g_str_is_ascii_valgrind (const char *str)
+-{
+-  size_t len = strlen (str);
+-
+-  utf8_verify_ascii (&str, &len);
+-
+-  return *str == 0;
+-}
+-
+-typedef gboolean (*GStrIsAsciiFunc) (const char *str);
+-
+-static GStrIsAsciiFunc
+-resolve_g_str_is_ascii (void)
+-{
+-  if (RUNNING_ON_VALGRIND)
+-    return g_str_is_ascii_valgrind;
+-  else
+-    return g_str_is_ascii_native;
+-}
+-#endif  /* HAVE_WORKING_IFUNC_ATTRIBUTE */
+-
+ /**
+  * g_str_is_ascii:
+  * @str: a string
+@@ -2012,18 +1900,13 @@ resolve_g_str_is_ascii (void)
+  *
+  * Since: 2.40
+  */
+-#if g_macro__has_attribute(no_sanitize_address)
+-  __attribute__((no_sanitize_address))
+-#endif
+ gboolean
+ g_str_is_ascii (const gchar *str)
+-#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
+-  __attribute__((ifunc ("resolve_g_str_is_ascii")));
+-#else
+ {
+-  return g_str_is_ascii_native (str);
++  utf8_verify_ascii (&str, NULL);
++
++  return *str == 0;
+ }
+-#endif
+ 
+ /**
+  * g_unichar_validate:
+-- 
+2.46.0
+

diff --git a/glib2.spec b/glib2.spec
index eff2b53..adf342c 100644
--- a/glib2.spec
+++ b/glib2.spec
@@ -18,6 +18,9 @@ Patch:          default-terminal.patch
 # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4406
 Patch:          0001-glib-gbytes-Be-more-careful-when-saving-a-GBytes-of-.patch
 
+# https://gitlab.gnome.org/GNOME/glib/-/issues/3526
+Patch: 0001-gutf8-Drop-ifunc-code-and-always-call-strlen-when-va.patch
+
 BuildRequires:  gcc
 BuildRequires:  gcc-c++
 BuildRequires:  gettext

                 reply	other threads:[~2026-08-11 10:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178644470598.1.6688365296865117533.rpms-glib2-7b0d00dfe8a9@fedoraproject.org \
    --to=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox