[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#1104976: unblock: glib2.0/2.84.2-1



Control: retitle -1 unblock: glib2.0/2.84.2-1
Control: tags -1 - confirmed

On Fri, 09 May 2025 at 11:08:26 +0100, Simon McVittie wrote:
[ Reason ]
CVE-2025-4373 (#1104930).

I also took the opportunity to catch up with the upstream glib-2-84
branch by adding one unrelated bugfix commit (a 1-line change).

Since then we've had a new upstream release, which I uploaded, in the interests of having a simpler diff and a simpler "what version is this?" story.

[ Reason ]

CVE-2025-4373 (#1104930) and other upstream bug fixes.

[ Impact ]

Fixes an out-of-bounds write if an attacker can somehow arrange for GLib to be acting on overwhelmingly large strings (half the address space in a single GString object, so 2GB for 32-bit processes).

Avoids potential negative string offsets in g_get_locale_variants() if the input is syntactically invalid (possibly found by fuzz-testing, might be claimed to be a security vulnerability if someone is parsing untrusted locale names for whatever reason).

Ensures that localtime_r() is not called without first calling tzset(), which has unspecified behaviour.

Makes it easier to take subsequent upstream stable releases, which can contain security fixes.

[ Tests ]

autopkgtests pass and my GNOME laptop continues to work well.

GLib has a quite thorough test suite in general, but CVE-2025-4373 is
not covered by it, because exploiting the bug requires a huge memory
allocation that will, in practice, usually fail.

[ Risks ]

Low-risk targeted changes.

The changes to glib/tests/utils.c are a bit noisy (changing some assertions around) but are purely test code, no impact on normal users (and the tests still pass). The additions in fuzzing/ are, again, a bit noisy, but I don't think we even compile that part; it certainly doesn't have any impact on end-user systems.

[ Checklist ]

  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing
      (filtered to exclude CI noise and the contents of deleted patches)

[ Other info ]

Needs a d-i ack due to the GTK-based graphical installer.
debdiff glib2.0*.dsc | filterdiff -p1 -x.gitlab-ci.yml -x'debian/patches/*'

-----

diffstat for glib2.0-2.84.1 glib2.0-2.84.2

 .gitlab-ci.yml                                                                |   30 -
 NEWS                                                                          |   16 
 debian/changelog                                                              |   45 ++
 debian/patches/gclosure-fix-ATOMIC_CHANGE_FIELD-to-read-vint-atomically.patch |   55 ---
 debian/patches/gfileutils-Preserve-mode-during-atomic-updates.patch           |    4 
 debian/patches/series                                                         |    1 
 debian/tests/manual/.gitignore                                                |    1 
 fuzzing/fuzz_get_locale_variants.c                                            |   45 ++
 fuzzing/meson.build                                                           |    1 
 gio/glocalfile.c                                                              |   11 
 girepository/girepository.c                                                   |    3 
 girepository/tests/repository-search-paths.c                                  |    2 
 glib/gcharset.c                                                               |    6 
 glib/gdate.c                                                                  |    1 
 glib/gstring.c                                                                |   36 +-
 glib/tests/utils.c                                                            |  168 +++++-----
 meson.build                                                                   |    2 
 17 files changed, 249 insertions(+), 178 deletions(-)

diff -Nru glib2.0-2.84.1/debian/changelog glib2.0-2.84.2/debian/changelog
--- glib2.0-2.84.1/debian/changelog	2025-04-24 20:26:06.000000000 +0100
+++ glib2.0-2.84.2/debian/changelog	2025-05-22 17:25:42.000000000 +0100
@@ -1,3 +1,48 @@
+glib2.0 (2.84.2-1) unstable; urgency=medium
+
+  * New upstream stable release
+    - Avoid potential negative string offsets in g_get_locale_variants()
+      if the input is syntactically invalid; add test and fuzzing coverage
+      (glib#3405 upstream)
+    - Minor improvements in tests (no effect on library)
+    - Don't use faccess() with flags on Android (no effect on Debian)
+    - Windows adjustments in girepository (no effect on Debian packages)
+    - CI updates (no effect on Debian packages)
+    - Other changes were already included in 2.84.1-3
+  * d/p/gclosure-fix-ATOMIC_CHANGE_FIELD-to-read-vint-atomically.patch,
+    d/p/gstring-carefully-handle-gssize-parameters.patch,
+    d/p/gstring-Make-len_unsigned-unsigned.patch,
+    d/p/gdate-Call-tzset-before-localtime_r.patch:
+    Drop patches from 2.84.1-2 and 2.84.1-3 that were included in the
+    upstream release
+
+ -- Simon McVittie <smcv@debian.org>  Thu, 22 May 2025 17:25:42 +0100
+
+glib2.0 (2.84.1-3) unstable; urgency=medium
+
+  [ Jeremy Bícha ]
+  * d/p/gfileutils-Preserve-mode-during-atomic-updates.patch:
+    Add a note that this fix for LP#2072586 was reverted in the upstream
+    2.84.x branch as a behaviour change. It was kept in 2.85.x,
+    and seems reasonable to keep for trixie.
+
+  [ Simon McVittie ]
+  * d/p/gfileutils-Preserve-mode-during-atomic-updates.patch:
+    Add a cross-reference to LP#2072586
+  * d/p/gstring-carefully-handle-gssize-parameters.patch,
+    d/p/gstring-Make-len_unsigned-unsigned.patch:
+    Add patches from upstream to fix a buffer underflow with very large
+    GString instances (Closes: #1104930, CVE-2025-4373)
+  * d/p/gdate-Call-tzset-before-localtime_r.patch:
+    Add patch from upstream to ensure that tzset() is called before
+    localtime_r(); otherwise the behaviour of localtime_r() is unspecified.
+  * These patches bring us up to date with upstream glib-2-84 branch commit
+    2.84.1-15-gb3de15acf9, excluding changes that are not relevant to
+    Debian architectures (macOS CI and Windows) and the revert of the fix
+    for LP#2072586 (discussed above).
+
+ -- Simon McVittie <smcv@debian.org>  Fri, 09 May 2025 15:01:35 +0100
+
 glib2.0 (2.84.1-2) unstable; urgency=medium
 
   * Cherry-pick 2 commits from glib-2-84 branch (LP: #2072586)
diff -Nru glib2.0-2.84.1/debian/tests/manual/.gitignore glib2.0-2.84.2/debian/tests/manual/.gitignore
--- glib2.0-2.84.1/debian/tests/manual/.gitignore	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.84.2/debian/tests/manual/.gitignore	2025-05-22 17:25:42.000000000 +0100
@@ -0,0 +1 @@
+/local-*.sources
diff -Nru glib2.0-2.84.1/fuzzing/fuzz_get_locale_variants.c glib2.0-2.84.2/fuzzing/fuzz_get_locale_variants.c
--- glib2.0-2.84.1/fuzzing/fuzz_get_locale_variants.c	1970-01-01 01:00:00.000000000 +0100
+++ glib2.0-2.84.2/fuzzing/fuzz_get_locale_variants.c	2025-05-20 17:22:25.000000000 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  - Philip Withnall <pwithnall@gnome.org>
+ */
+
+#include "fuzz.h"
+
+int
+LLVMFuzzerTestOneInput (const unsigned char *data, size_t size)
+{
+  unsigned char *nul_terminated_data = NULL;
+  char **v;
+
+  fuzz_set_logging_func ();
+
+  /* ignore @size (g_get_locale_variants() doesn’t support it); ensure @data is nul-terminated */
+  nul_terminated_data = (unsigned char *) g_strndup ((const char *) data, size);
+
+  v = g_get_locale_variants ((char *) nul_terminated_data);
+  g_assert_nonnull (v);
+  /* g_get_locale_variants() guarantees that the input is always in the output: */
+  g_assert_true (g_strv_contains ((const char * const *) v, (char *) nul_terminated_data));
+  g_strfreev (v);
+
+  g_free (nul_terminated_data);
+
+  return 0;
+}
diff -Nru glib2.0-2.84.1/fuzzing/meson.build glib2.0-2.84.2/fuzzing/meson.build
--- glib2.0-2.84.1/fuzzing/meson.build	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/fuzzing/meson.build	2025-05-20 17:22:25.000000000 +0100
@@ -25,6 +25,7 @@
   'fuzz_date_parse',
   'fuzz_date_time_new_from_iso8601',
   'fuzz_dbus_message',
+  'fuzz_get_locale_variants',
   'fuzz_inet_address_mask_new_from_string',
   'fuzz_inet_address_new_from_string',
   'fuzz_inet_socket_address_new_from_string',
diff -Nru glib2.0-2.84.1/gio/glocalfile.c glib2.0-2.84.2/gio/glocalfile.c
--- glib2.0-2.84.1/gio/glocalfile.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/gio/glocalfile.c	2025-05-20 17:22:25.000000000 +0100
@@ -1260,8 +1260,13 @@
 }
 
 /* FIXME: faccessat() is available on FreeBSD but appears to not work correctly
- * here. This needs diagnosing; https://gitlab.gnome.org/GNOME/glib/-/issues/3495 */
-#if defined(HAVE_FACCESSAT) && !defined(__FreeBSD__)
+ * here. This needs diagnosing; https://gitlab.gnome.org/GNOME/glib/-/issues/3495
+ *
+ * On Android (bionic as of 2015-02-24), faccess() returns EINVAL if any flags are set,
+ * so we have to use the fallback path. See
+ * https://cs.android.com/android/_/android/platform/bionic/+/35778253a5ed71e87a608ca590b63729d9f88567
+ */
+#if defined(HAVE_FACCESSAT) && !defined(__FreeBSD__) && !defined(__ANDROID__)
 static gboolean
 g_local_file_query_exists (GFile        *file,
                            GCancellable *cancellable)
@@ -3155,7 +3160,7 @@
   iface->monitor_dir = g_local_file_monitor_dir;
   iface->monitor_file = g_local_file_monitor_file;
   iface->measure_disk_usage = g_local_file_measure_disk_usage;
-#if defined(HAVE_FACCESSAT) && !defined(__FreeBSD__)
+#if defined(HAVE_FACCESSAT) && !defined(__FreeBSD__) && !defined(__ANDROID__)
   iface->query_exists = g_local_file_query_exists;
 #endif
 
diff -Nru glib2.0-2.84.1/girepository/girepository.c glib2.0-2.84.2/girepository/girepository.c
--- glib2.0-2.84.1/girepository/girepository.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/girepository/girepository.c	2025-05-20 17:22:25.000000000 +0100
@@ -140,8 +140,6 @@
 
 static HMODULE girepository_dll = NULL;
 
-#ifdef DLL_EXPORT
-
 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
 
 BOOL WINAPI
@@ -155,7 +153,6 @@
   return TRUE;
 }
 
-#endif /* DLL_EXPORT */
 #endif /* G_PLATFORM_WIN32 */
 
 #ifdef __APPLE__
diff -Nru glib2.0-2.84.1/girepository/tests/repository-search-paths.c glib2.0-2.84.2/girepository/tests/repository-search-paths.c
--- glib2.0-2.84.1/girepository/tests/repository-search-paths.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/girepository/tests/repository-search-paths.c	2025-05-20 17:22:25.000000000 +0100
@@ -27,7 +27,7 @@
 {
 #if defined(G_PLATFORM_WIN32)
   const char *tests_build_dir = g_getenv ("G_TEST_BUILDDIR");
-  char *expected_rel_path = g_build_filename (tests_build_dir, "lib", "girepository-1.0", NULL);
+  char *expected_rel_path = g_build_filename (tests_build_dir, "..", "lib", "girepository-1.0", NULL);
 #elif defined(__APPLE__)
   const char *tests_build_dir = g_getenv ("G_TEST_BUILDDIR");
   char *expected_rel_path = g_build_filename (tests_build_dir, "..", "girepository-1.0", NULL);
diff -Nru glib2.0-2.84.1/glib/gcharset.c glib2.0-2.84.2/glib/gcharset.c
--- glib2.0-2.84.1/glib/gcharset.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/glib/gcharset.c	2025-05-20 17:22:25.000000000 +0100
@@ -537,6 +537,7 @@
 };
 
 /* Break an X/Open style locale specification into components
+ * e.g. `en_GB` or `uz_UZ.utf8@cyrillic`
  */
 static guint
 explode_locale (const gchar *locale,
@@ -563,7 +564,7 @@
   else
     at_pos = locale + strlen (locale);
 
-  if (dot_pos)
+  if (dot_pos && dot_pos < at_pos)
     {
       mask |= COMPONENT_CODESET;
       *codeset = g_strndup (dot_pos, at_pos - dot_pos);
@@ -571,7 +572,7 @@
   else
     dot_pos = at_pos;
 
-  if (uscore_pos)
+  if (uscore_pos && uscore_pos < dot_pos)
     {
       mask |= COMPONENT_TERRITORY;
       *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
@@ -579,6 +580,7 @@
   else
     uscore_pos = dot_pos;
 
+  g_assert (uscore_pos >= locale);
   *language = g_strndup (locale, uscore_pos - locale);
 
   return mask;
diff -Nru glib2.0-2.84.1/glib/gdate.c glib2.0-2.84.2/glib/gdate.c
--- glib2.0-2.84.1/glib/gdate.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/glib/gdate.c	2025-05-20 17:22:25.000000000 +0100
@@ -1392,6 +1392,7 @@
   gboolean success = TRUE;
 
 #ifdef HAVE_LOCALTIME_R
+  tzset ();
   if (!localtime_r (&timet, out_tm))
     success = FALSE;
 #else
diff -Nru glib2.0-2.84.1/glib/gstring.c glib2.0-2.84.2/glib/gstring.c
--- glib2.0-2.84.1/glib/gstring.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/glib/gstring.c	2025-05-20 17:22:25.000000000 +0100
@@ -480,8 +480,9 @@
     return string;
 
   if (len < 0)
-    len = strlen (val);
-  len_unsigned = len;
+    len_unsigned = strlen (val);
+  else
+    len_unsigned = len;
 
   if (pos < 0)
     pos_unsigned = string->len;
@@ -778,10 +779,12 @@
   g_string_maybe_expand (string, 1);
 
   if (pos < 0)
-    pos = string->len;
+    pos_unsigned = string->len;
   else
-    g_return_val_if_fail ((gsize) pos <= string->len, string);
-  pos_unsigned = pos;
+    {
+      pos_unsigned = pos;
+      g_return_val_if_fail (pos_unsigned <= string->len, string);
+    }
 
   /* If not just an append, move the old stuff */
   if (pos_unsigned < string->len)
@@ -814,6 +817,7 @@
                          gssize    pos,
                          gunichar  wc)
 {
+  gsize pos_unsigned;
   gint charlen, first, i;
   gchar *dest;
 
@@ -855,15 +859,18 @@
   g_string_maybe_expand (string, charlen);
 
   if (pos < 0)
-    pos = string->len;
+    pos_unsigned = string->len;
   else
-    g_return_val_if_fail ((gsize) pos <= string->len, string);
+    {
+      pos_unsigned = pos;
+      g_return_val_if_fail (pos_unsigned <= string->len, string);
+    }
 
   /* If not just an append, move the old stuff */
-  if ((gsize) pos < string->len)
-    memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
+  if (pos_unsigned < string->len)
+    memmove (string->str + pos_unsigned + charlen, string->str + pos_unsigned, string->len - pos_unsigned);
 
-  dest = string->str + pos;
+  dest = string->str + pos_unsigned;
   /* Code copied from g_unichar_to_utf() */
   for (i = charlen - 1; i > 0; --i)
     {
@@ -921,6 +928,7 @@
                         const gchar *val,
                         gssize       len)
 {
+  gsize len_unsigned;
   gsize end;
 
   g_return_val_if_fail (string != NULL, NULL);
@@ -932,14 +940,16 @@
   g_return_val_if_fail (pos <= string->len, string);
 
   if (len < 0)
-    len = strlen (val);
+    len_unsigned = strlen (val);
+  else
+    len_unsigned = len;
 
-  end = pos + len;
+  end = pos + len_unsigned;
 
   if (end > string->len)
     g_string_maybe_expand (string, end - string->len);
 
-  memcpy (string->str + pos, val, len);
+  memcpy (string->str + pos, val, len_unsigned);
 
   if (end > string->len)
     {
diff -Nru glib2.0-2.84.1/glib/tests/utils.c glib2.0-2.84.2/glib/tests/utils.c
--- glib2.0-2.84.1/glib/tests/utils.c	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/glib/tests/utils.c	2025-05-20 17:22:25.000000000 +0100
@@ -42,29 +42,6 @@
 #include <windows.h>
 #endif
 
-static gboolean
-strv_check (const gchar * const *strv, ...)
-{
-  va_list args;
-  gchar *s;
-  gint i;
-
-  va_start (args, strv);
-  for (i = 0; strv[i]; i++)
-    {
-      s = va_arg (args, gchar*);
-      if (g_strcmp0 (strv[i], s) != 0)
-        {
-          va_end (args);
-          return FALSE;
-        }
-    }
-
-  va_end (args);
-
-  return TRUE;
-}
-
 static void
 test_language_names (void)
 {
@@ -72,35 +49,62 @@
 
   g_setenv ("LANGUAGE", "de:en_US", TRUE);
   names = g_get_language_names ();
-  g_assert (strv_check (names, "de", "en_US", "en", "C", NULL));
+  g_assert_cmpstrv (names, ((const char *[]) { "de", "en_US", "en", "C", NULL }));
 
   g_setenv ("LANGUAGE", "tt_RU.UTF-8@iqtelif", TRUE);
   names = g_get_language_names ();
-  g_assert (strv_check (names,
-                        "tt_RU.UTF-8@iqtelif",
-                        "tt_RU@iqtelif",
-                        "tt.UTF-8@iqtelif",
-                        "tt@iqtelif",
-                        "tt_RU.UTF-8",
-                        "tt_RU",
-                        "tt.UTF-8",
-                        "tt",
-                        "C",
-                        NULL));
+  g_assert_cmpstrv (names,
+                    ((const char *[]) {
+                      "tt_RU.UTF-8@iqtelif",
+                      "tt_RU@iqtelif",
+                      "tt.UTF-8@iqtelif",
+                      "tt@iqtelif",
+                      "tt_RU.UTF-8",
+                      "tt_RU",
+                      "tt.UTF-8",
+                      "tt",
+                      "C",
+                      NULL
+                    }));
 }
 
 static void
 test_locale_variants (void)
 {
-  char **v;
+  const struct
+    {
+      const char *locale_str;
+      const char * const *expected_variants;
+    }
+  vectors[] =
+    {
+      /* Try some valid locales */
+      { "en", (const char *[]) { "en", NULL } },
+      { "sr@latin", (const char *[]) { "sr@latin", "sr", NULL } },
+      { "fr_BE", (const char *[]) { "fr_BE", "fr", NULL } },
+      { "sr_SR@latin", (const char *[]) { "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL } },
+      { "sr_SR@latin.UTF-8", (const char *[]) { "sr_SR@latin.UTF-8", "sr_SR@latin", "sr.UTF-8", "sr", NULL } },
+
+      /* And some invalid ones. The parser should try and extract what value it can */
+      { "sr@latin_invalid", (const char *[]) { "sr@latin_invalid", "sr@latin", NULL } },
+      { "sr.UTF-8@latin", (const char *[]) { "sr.UTF-8@latin", "sr@latin", "sr.UTF-8", "sr", NULL } },
+      { "sr.UTF-8_latin", (const char *[]) { "sr.UTF-8_latin", "sr.UTF-8", NULL } },
+      { "sr.UTF-8@latin_invalid", (const char *[]) { "sr.UTF-8@latin_invalid", "sr.UTF-8@latin", NULL } },
+    };
+  size_t i;
+
+  for (i = 0; i < G_N_ELEMENTS (vectors); i++)
+    {
+      char **v;
+
+      g_test_message ("Testing locale ‘%s’", vectors[i].locale_str);
 
-  v = g_get_locale_variants ("fr_BE");
-  g_assert (strv_check ((const gchar * const *) v, "fr_BE", "fr", NULL));
-  g_strfreev (v);
-
-  v = g_get_locale_variants ("sr_SR@latin");
-  g_assert (strv_check ((const gchar * const *) v, "sr_SR@latin", "sr@latin", "sr_SR", "sr", NULL));
-  g_strfreev (v);
+      v = g_get_locale_variants (vectors[i].locale_str);
+      g_assert_cmpstrv (v, vectors[i].expected_variants);
+      /* g_get_locale_variants() guarantees that the input is always in the output: */
+      g_assert_true (g_strv_contains ((const char * const *) v, vectors[i].locale_str));
+      g_strfreev (v);
+    }
 }
 
 static void
@@ -111,27 +115,27 @@
               GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION,
               glib_major_version, glib_minor_version, glib_micro_version);
 
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION,
-                                GLIB_MINOR_VERSION,
-                                GLIB_MICRO_VERSION) == NULL);
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION,
-                                GLIB_MINOR_VERSION,
-                                0) == NULL);
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION - 1,
-                                0,
-                                0) != NULL);
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION + 1,
-                                0,
-                                0) != NULL);
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION,
-                                GLIB_MINOR_VERSION + 1,
-                                0) != NULL);
+  g_assert_null (glib_check_version (GLIB_MAJOR_VERSION,
+                                     GLIB_MINOR_VERSION,
+                                     GLIB_MICRO_VERSION));
+  g_assert_null (glib_check_version (GLIB_MAJOR_VERSION,
+                                     GLIB_MINOR_VERSION,
+                                     0));
+  g_assert_nonnull (glib_check_version (GLIB_MAJOR_VERSION - 1,
+                                        0,
+                                        0));
+  g_assert_nonnull (glib_check_version (GLIB_MAJOR_VERSION + 1,
+                                        0,
+                                        0));
+  g_assert_nonnull (glib_check_version (GLIB_MAJOR_VERSION,
+                                        GLIB_MINOR_VERSION + 1,
+                                        0));
   /* don't use + 1 here, since a +/-1 difference can
    * happen due to post-release version bumps in git
    */
-  g_assert (glib_check_version (GLIB_MAJOR_VERSION,
-                                GLIB_MINOR_VERSION,
-                                GLIB_MICRO_VERSION + 3) != NULL);
+  g_assert_nonnull (glib_check_version (GLIB_MAJOR_VERSION,
+                                        GLIB_MINOR_VERSION,
+                                        GLIB_MICRO_VERSION + 3));
 }
 
 static const gchar *argv0;
@@ -463,11 +467,11 @@
   gsize i;
 
   res = g_find_program_in_path ("sh");
-  g_assert (res != NULL);
+  g_assert_nonnull (res);
   g_free (res);
 
   res = g_find_program_in_path ("/bin/sh");
-  g_assert (res != NULL);
+  g_assert_nonnull (res);
   g_free (res);
 
   /* Resolve any symlinks in the CWD as that breaks the test e.g.
@@ -499,13 +503,13 @@
 #endif
 
   res = g_find_program_in_path ("this_program_does_not_exit");
-  g_assert (res == NULL);
+  g_assert_null (res);
 
   res = g_find_program_in_path ("/bin");
-  g_assert (res == NULL);
+  g_assert_null (res);
 
   res = g_find_program_in_path ("/etc/passwd");
-  g_assert (res == NULL);
+  g_assert_null (res);
 }
 
 static char *
@@ -789,7 +793,7 @@
 
   name = g_get_user_name ();
 
-  g_assert (name != NULL);
+  g_assert_nonnull (name);
 }
 
 static void
@@ -799,7 +803,7 @@
 
   name = g_get_real_name ();
 
-  g_assert (name != NULL);
+  g_assert_nonnull (name);
 }
 
 static void
@@ -809,7 +813,7 @@
 
   name = g_get_host_name ();
 
-  g_assert (name != NULL);
+  g_assert_nonnull (name);
   g_assert_true (g_utf8_validate (name, -1, NULL));
 }
 
@@ -899,11 +903,11 @@
   const gchar *dir, *dir2;
 
   dir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
-  g_assert (dir != NULL);
+  g_assert_nonnull (dir);
 
   g_reload_user_special_dirs_cache ();
   dir2 = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
-  g_assert (dir2 != NULL);
+  g_assert_nonnull (dir2);
 }
 
 static void
@@ -970,11 +974,11 @@
 
   a = g_malloc (5);
   g_clear_pointer (&a, g_free);
-  g_assert (a == NULL);
+  g_assert_null (a);
 
   a = g_malloc (5);
   (g_clear_pointer) (&a, g_free);
-  g_assert (a == NULL);
+  g_assert_null (a);
 }
 
 /* Test that g_clear_pointer() works with a GDestroyNotify which contains a cast.
@@ -1046,15 +1050,15 @@
   get_obj (NULL);
 
   get_obj (&a);
-  g_assert (a);
+  g_assert_nonnull (a);
 
   /* ensure that it works to skip the macro */
   b = (g_steal_pointer) (&a);
-  g_assert (!a);
+  g_assert_null (a);
   obj_count--;
   g_free (b);
 
-  g_assert (!obj_count);
+  g_assert_cmpint (obj_count, ==, 0);
 }
 
 static void
@@ -1063,16 +1067,16 @@
   gpointer a;
 
   a = g_try_malloc (0);
-  g_assert (a == NULL);
+  g_assert_null (a);
 
   a = g_try_malloc0 (0);
-  g_assert (a == NULL);
+  g_assert_null (a);
 
   a = g_malloc (16);
   a = g_try_realloc (a, 20);
   a = g_try_realloc (a, 0);
 
-  g_assert (a == NULL);
+  g_assert_null (a);
 }
 
 static void
@@ -1209,11 +1213,11 @@
 {
   gpointer p = &test_nullify;
 
-  g_assert (p != NULL);
+  g_assert_nonnull (p);
 
   g_nullify_pointer (&p);
 
-  g_assert (p == NULL);
+  g_assert_null (p);
 }
 
 static void
@@ -1241,7 +1245,7 @@
   gboolean res;
 
   res = GLIB_PRIVATE_CALL(g_check_setuid) ();
-  g_assert (!res);
+  g_assert_false (res);
 }
 
 /* Test the defined integer limits are correct, as some compilers have had
diff -Nru glib2.0-2.84.1/meson.build glib2.0-2.84.2/meson.build
--- glib2.0-2.84.1/meson.build	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/meson.build	2025-05-20 17:22:25.000000000 +0100
@@ -1,5 +1,5 @@
 project('glib', 'c',
-  version : '2.84.1',
+  version : '2.84.2',
   # NOTE: See the policy in docs/meson-version.md before changing the Meson dependency
   meson_version : '>= 1.4.0',
   default_options : [
diff -Nru glib2.0-2.84.1/NEWS glib2.0-2.84.2/NEWS
--- glib2.0-2.84.1/NEWS	2025-04-03 15:38:51.000000000 +0100
+++ glib2.0-2.84.2/NEWS	2025-05-20 17:22:25.000000000 +0100
@@ -1,3 +1,19 @@
+Overview of changes in GLib 2.84.2, 2025-05-20
+==============================================
+
+* Bugs fixed:
+  - !4576 Backport !4575 “gclosure: fix ATOMIC_CHANGE_FIELD to read vint
+    atomically” to glib-2-84
+  - !4595 Backport !4582 “Windows: fix wrong typelib path” to glib-2-84
+  - !4614 Backport "gstring: carefully handle gssize parameters"
+  - !4616 Backport !4613 “Update macOS job for new CI runner” to glib-2-84
+  - !4623 Backport !4617 “gdate: Call tzset before localtime_r” to glib-2-84
+  - !4639 Backport -Wsign-conversion fixes for g_get_locale_variants() from
+    !4590 to glib-2-84
+  - !4640 Backport !4620 “glocalfile: Disable faccessat()-based query_exists on
+    Android” to glib-2-84
+
+
 Overview of changes in GLib 2.84.1, 2025-04-03
 ==============================================
 

Reply to: