new file mode 100644
@@ -0,0 +1,42 @@
+From 662aa569efa65eaa4672ab0671eb8533a354cd89 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
+Date: Wed, 21 Jan 2026 22:00:17 +0100
+Subject: [PATCH] guniprop: Use size_t for output_marks length
+
+The input string length may overflow, and this would lead to wrong
+behavior and invalid writes.
+
+Spotted by treeplus.
+Thanks to the Sovereign Tech Resilience programme from the Sovereign
+Tech Agency.
+
+ID: #YWH-PGM9867-171
+Closes: #3872
+
+CVE: CVE-2026-1489
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/662aa569efa65eaa4672ab0671eb8533a354cd89]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ glib/guniprop.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/glib/guniprop.c b/glib/guniprop.c
+index fe0033fd6..1a0cc6408 100644
+--- a/glib/guniprop.c
++++ b/glib/guniprop.c
+@@ -772,13 +772,13 @@ get_locale_type (void)
+ return LOCALE_NORMAL;
+ }
+
+-static gint
++static size_t
+ output_marks (const char **p_inout,
+ char *out_buffer,
+ gboolean remove_dot)
+ {
+ const char *p = *p_inout;
+- gint len = 0;
++ size_t len = 0;
+
+ while (*p)
+ {
new file mode 100644
@@ -0,0 +1,30 @@
+From 58356619525a1d565df8cc348e9784716f020f2f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
+Date: Wed, 21 Jan 2026 22:01:49 +0100
+Subject: [PATCH] guniprop: Do not convert size_t to gint
+
+We were correctly using size_t in output_special_case() since commit
+362f92b69, but then we converted the value back to int
+
+Related to: #3872
+
+CVE: CVE-2026-1489
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/58356619525a1d565df8cc348e9784716f020f2f]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ glib/guniprop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/glib/guniprop.c b/glib/guniprop.c
+index 1a0cc6408..fe50a287c 100644
+--- a/glib/guniprop.c
++++ b/glib/guniprop.c
+@@ -798,7 +798,7 @@ output_marks (const char **p_inout,
+ return len;
+ }
+
+-static gint
++static size_t
+ output_special_case (gchar *out_buffer,
+ int offset,
+ int type,
new file mode 100644
@@ -0,0 +1,290 @@
+From 170dc8c4068db4c4cbf63c7d27192e230436da21 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
+Date: Wed, 21 Jan 2026 22:04:22 +0100
+Subject: [PATCH] guniprop: Ensure we do not overflow size in
+ g_utf8_{strdown,gstrup}()
+
+While this is technically not a security issue, when repeatedly adding
+to a size_t value, we can overflow and start from 0.
+
+Now, while being unlikely, technically an utf8 lower or upper string can
+have a longer size than the input value, and if the output string is
+bigger than G_MAXSIZE we'd end up cutting it silently.
+
+Let's instead assert each time we increase the output length
+
+CVE: CVE-2026-1489
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/170dc8c4068db4c4cbf63c7d27192e230436da21]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ glib/guniprop.c | 109 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 70 insertions(+), 39 deletions(-)
+
+diff --git a/glib/guniprop.c b/glib/guniprop.c
+index fe50a287c..86020b6e0 100644
+--- a/glib/guniprop.c
++++ b/glib/guniprop.c
+@@ -772,14 +772,36 @@ get_locale_type (void)
+ return LOCALE_NORMAL;
+ }
+
+-static size_t
+-output_marks (const char **p_inout,
+- char *out_buffer,
+- gboolean remove_dot)
++G_ALWAYS_INLINE static inline void
++increase_size (size_t *sizeptr, size_t add)
++{
++ g_assert (G_MAXSIZE - *(sizeptr) >= add);
++ *(sizeptr) += add;
++}
++
++G_ALWAYS_INLINE static inline void
++append_utf8_char_to_buffer (gunichar c,
++ char *out_buffer,
++ size_t *in_out_len)
++{
++ gint utf8_len;
++ char *buffer;
++
++ buffer = out_buffer ? out_buffer + *(in_out_len) : NULL;
++ utf8_len = g_unichar_to_utf8 (c, buffer);
++
++ g_assert (utf8_len >= 0);
++ increase_size (in_out_len, utf8_len);
++}
++
++static void
++append_mark (const char **p_inout,
++ char *out_buffer,
++ size_t *in_out_len,
++ gboolean remove_dot)
+ {
+ const char *p = *p_inout;
+- size_t len = 0;
+-
++
+ while (*p)
+ {
+ gunichar c = g_utf8_get_char (p);
+@@ -787,7 +809,7 @@ output_marks (const char **p_inout,
+ if (ISMARK (TYPE (c)))
+ {
+ if (!remove_dot || c != 0x307 /* COMBINING DOT ABOVE */)
+- len += g_unichar_to_utf8 (c, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (c, out_buffer, in_out_len);
+ p = g_utf8_next_char (p);
+ }
+ else
+@@ -795,14 +817,14 @@ output_marks (const char **p_inout,
+ }
+
+ *p_inout = p;
+- return len;
+ }
+
+-static size_t
+-output_special_case (gchar *out_buffer,
+- int offset,
+- int type,
+- int which)
++static void
++append_special_case (char *out_buffer,
++ size_t *in_out_len,
++ int offset,
++ int type,
++ int which)
+ {
+ const gchar *p = special_case_table + offset;
+ gint len;
+@@ -814,10 +836,12 @@ output_special_case (gchar *out_buffer,
+ p += strlen (p) + 1;
+
+ len = strlen (p);
+- if (out_buffer)
+- memcpy (out_buffer, p, len);
++ g_assert (len < G_MAXSIZE - *in_out_len);
+
+- return len;
++ if (out_buffer)
++ memcpy (out_buffer + *in_out_len, p, len);
++
++ increase_size (in_out_len, len);
+ }
+
+ static gsize
+@@ -858,11 +882,13 @@ real_toupper (const gchar *str,
+ decomp_len = g_unichar_fully_decompose (c, FALSE, decomp, G_N_ELEMENTS (decomp));
+ for (i=0; i < decomp_len; i++)
+ {
++
+ if (decomp[i] != 0x307 /* COMBINING DOT ABOVE */)
+- len += g_unichar_to_utf8 (g_unichar_toupper (decomp[i]), out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (g_unichar_toupper (decomp[i]),
++ out_buffer, &len);
+ }
+-
+- len += output_marks (&p, out_buffer ? out_buffer + len : NULL, TRUE);
++
++ append_mark (&p, out_buffer, &len, TRUE);
+
+ continue;
+ }
+@@ -875,17 +901,17 @@ real_toupper (const gchar *str,
+ if (locale_type == LOCALE_TURKIC && c == 'i')
+ {
+ /* i => LATIN CAPITAL LETTER I WITH DOT ABOVE */
+- len += g_unichar_to_utf8 (0x130, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x130, out_buffer, &len);
+ }
+ else if (c == 0x0345) /* COMBINING GREEK YPOGEGRAMMENI */
+ {
+ /* Nasty, need to move it after other combining marks .. this would go away if
+ * we normalized first.
+ */
+- len += output_marks (&p, out_buffer ? out_buffer + len : NULL, FALSE);
++ append_mark (&p, out_buffer, &len, TRUE);
+
+ /* And output as GREEK CAPITAL LETTER IOTA */
+- len += g_unichar_to_utf8 (0x399, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x399, out_buffer, &len);
+ }
+ else if (IS (t,
+ OR (G_UNICODE_LOWERCASE_LETTER,
+@@ -896,8 +922,8 @@ real_toupper (const gchar *str,
+
+ if (val >= 0x1000000)
+ {
+- len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t,
+- t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1);
++ append_special_case (out_buffer, &len, val - 0x1000000, t,
++ t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1);
+ }
+ else
+ {
+@@ -917,7 +943,7 @@ real_toupper (const gchar *str,
+ /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR,
+ * do not have an uppercase equivalent, in which case val will be
+ * zero. */
+- len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (val ? val : c, out_buffer, &len);
+ }
+ }
+ else
+@@ -927,7 +953,7 @@ real_toupper (const gchar *str,
+ if (out_buffer)
+ memcpy (out_buffer + len, last, char_len);
+
+- len += char_len;
++ increase_size (&len, char_len);
+ }
+
+ }
+@@ -965,6 +991,8 @@ g_utf8_strup (const gchar *str,
+ * We use a two pass approach to keep memory management simple
+ */
+ result_len = real_toupper (str, len, NULL, locale_type);
++ g_assert (result_len < G_MAXSIZE);
++
+ result = g_malloc (result_len + 1);
+ real_toupper (str, len, result, locale_type);
+ result[result_len] = '\0';
+@@ -1022,14 +1050,15 @@ real_tolower (const gchar *str,
+ {
+ /* I + COMBINING DOT ABOVE => i (U+0069)
+ * LATIN CAPITAL LETTER I WITH DOT ABOVE => i (U+0069) */
+- len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x0069, out_buffer, &len);
++
+ if (combining_dot)
+ p = g_utf8_next_char (p);
+ }
+ else
+ {
+ /* I => LATIN SMALL LETTER DOTLESS I */
+- len += g_unichar_to_utf8 (0x131, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x131, out_buffer, &len);
+ }
+ }
+ /* Introduce an explicit dot above when lowercasing capital I's and J's
+@@ -1037,19 +1066,19 @@ real_tolower (const gchar *str,
+ else if (locale_type == LOCALE_LITHUANIAN &&
+ (c == 0x00cc || c == 0x00cd || c == 0x0128))
+ {
+- len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL);
+- len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x0069, out_buffer, &len);
++ append_utf8_char_to_buffer (0x0307, out_buffer, &len);
+
+ switch (c)
+ {
+ case 0x00cc:
+- len += g_unichar_to_utf8 (0x0300, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x0300, out_buffer, &len);
+ break;
+ case 0x00cd:
+- len += g_unichar_to_utf8 (0x0301, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x0301, out_buffer, &len);
+ break;
+ case 0x0128:
+- len += g_unichar_to_utf8 (0x0303, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (0x0303, out_buffer, &len);
+ break;
+ }
+ }
+@@ -1058,8 +1087,8 @@ real_tolower (const gchar *str,
+ c == 'J' || c == G_UNICHAR_FULLWIDTH_J || c == 0x012e) &&
+ has_more_above (p))
+ {
+- len += g_unichar_to_utf8 (g_unichar_tolower (c), out_buffer ? out_buffer + len : NULL);
+- len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (g_unichar_tolower (c), out_buffer, &len);
++ append_utf8_char_to_buffer (0x0307, out_buffer, &len);
+ }
+ else if (c == 0x03A3) /* GREEK CAPITAL LETTER SIGMA */
+ {
+@@ -1082,7 +1111,7 @@ real_tolower (const gchar *str,
+ else
+ val = 0x3c2; /* GREEK SMALL FINAL SIGMA */
+
+- len += g_unichar_to_utf8 (val, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (val, out_buffer, &len);
+ }
+ else if (IS (t,
+ OR (G_UNICODE_UPPERCASE_LETTER,
+@@ -1093,7 +1122,7 @@ real_tolower (const gchar *str,
+
+ if (val >= 0x1000000)
+ {
+- len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t, 0);
++ append_special_case (out_buffer, &len, val - 0x1000000, t, 0);
+ }
+ else
+ {
+@@ -1112,7 +1141,7 @@ real_tolower (const gchar *str,
+
+ /* Not all uppercase letters are guaranteed to have a lowercase
+ * equivalent. If this is the case, val will be zero. */
+- len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
++ append_utf8_char_to_buffer (val ? val : c, out_buffer, &len);
+ }
+ }
+ else
+@@ -1122,7 +1151,7 @@ real_tolower (const gchar *str,
+ if (out_buffer)
+ memcpy (out_buffer + len, last, char_len);
+
+- len += char_len;
++ increase_size (&len, char_len);
+ }
+
+ }
+@@ -1159,6 +1188,8 @@ g_utf8_strdown (const gchar *str,
+ * We use a two pass approach to keep memory management simple
+ */
+ result_len = real_tolower (str, len, NULL, locale_type);
++ g_assert (result_len < G_MAXSIZE);
++
+ result = g_malloc (result_len + 1);
+ real_tolower (str, len, result, locale_type);
+ result[result_len] = '\0';
new file mode 100644
@@ -0,0 +1,68 @@
+From b96966058f4291db8970ced70ee22103e63679e5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
+Date: Fri, 23 Jan 2026 17:39:34 +0100
+Subject: [PATCH] glib/tests/unicode: Add test debug information when parsing
+ input files
+
+On case of failures makes it easier to understand on what line of the
+source file we're at, as it might not be clear for non-ascii chars
+
+CVE: CVE-2026-1489
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/b96966058f4291db8970ced70ee22103e63679e5]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ glib/tests/unicode.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/glib/tests/unicode.c b/glib/tests/unicode.c
+index 90b5a98b8..44d1083dd 100644
+--- a/glib/tests/unicode.c
++++ b/glib/tests/unicode.c
+@@ -600,6 +600,7 @@ test_casemap_and_casefold (void)
+ const char *locale;
+ const char *test;
+ const char *expected;
++ size_t line = 0;
+ char *convert;
+ char *current_locale = setlocale (LC_CTYPE, NULL);
+ char *old_lc_all, *old_lc_messages, *old_lang;
+@@ -620,6 +621,7 @@ test_casemap_and_casefold (void)
+
+ while (fgets (buffer, sizeof (buffer), infile))
+ {
++ line++;
+ if (buffer[0] == '#')
+ continue;
+
+@@ -662,6 +664,9 @@ test_casemap_and_casefold (void)
+
+ convert = g_utf8_strup (test, -1);
+ expected = strings[4][0] ? strings[4] : test;
++ g_test_message ("Converting '%s' => '%s' (line %" G_GSIZE_FORMAT ")",
++ test, expected, line);
++
+ g_assert_cmpstr (convert, ==, expected);
+ g_free (convert);
+
+@@ -681,9 +686,11 @@ test_casemap_and_casefold (void)
+
+ infile = fopen (filename, "r");
+ g_assert (infile != NULL);
++ line = 0;
+
+ while (fgets (buffer, sizeof (buffer), infile))
+ {
++ line++;
+ if (buffer[0] == '#')
+ continue;
+
+@@ -693,6 +700,9 @@ test_casemap_and_casefold (void)
+ test = strings[0];
+
+ convert = g_utf8_casefold (test, -1);
++ g_test_message ("Converting '%s' => '%s' (line %" G_GSIZE_FORMAT ")",
++ test, strings[1], line);
++
+ g_assert_cmpstr (convert, ==, strings[1]);
+ g_free (convert);
+
@@ -43,6 +43,10 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \
file://CVE-2026-1484-01.patch \
file://CVE-2026-1484-02.patch \
file://CVE-2026-1485.patch \
+ file://CVE-2026-1489-01.patch \
+ file://CVE-2026-1489-02.patch \
+ file://CVE-2026-1489-03.patch \
+ file://CVE-2026-1489-04.patch \
"
SRC_URI:append:class-native = " file://relocate-modules.patch \
file://0001-meson.build-do-not-enable-pidfd-features-on-native-g.patch \