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

Bug#1111470: trixie-pu: package glib2.0/2.84.4-3~deb13u1



Package: release.debian.org
Severity: normal
Tags: trixie d-i
X-Debbugs-Cc: glib2.0@packages.debian.org, debian-boot@lists.debian.org
Control: affects -1 + src:glib2.0
User: release.debian.org@packages.debian.org
Usertags: pu

I'd like to backport the GLib from unstable into trixie for 13.1. We've 
intentionally been keeping most of GNOME 49 in experimental for now, to 
get wider testing for the first round of what will become stable updates
to trixie's GNOME 48.

Or, if this is too many changes, I'd like to at least backport the 
preinst and postrm changes for #1110696, and preferably the new upstream 
release as well - but that would already be most of the changes proposed 
here, at which point we might as well benefit from the full set having 
been tested by users of unstable.

Please let me know whether I can upload as-is, or whether I should do a 
respin of this with a reduced scope.

[ Reason / Impact ]

1. #1110696. There's a corner case in the upgrade path from bookworm to
   trixie that results in functionally necessary files from GLib being
   deleted, causing most GLib/GTK apps to crash out with a fatal error
   until it is worked around with `dpkg-reconfigure libglib2.0-0t64`.
   (This is a special case of #1065022.)

   To reproduce:
   - start on bookworm or older
   - install libglib2.0-0 for a foreign architecture (typically i386)
   - remove all packages from the foreign arch without purging libglib2.0-0
   - remove the foreign arch from dpkg's configuration
   - upgrade to trixie
   - purge the foreign architecture's libglib2.0-0

   Related to #1065022 and #1110696, I made the postrm safer for the
   future: if it detects that there are still GSettings schemas or
   GIO modules present during purge, it will not delete the relevant
   generated files, guarding against accidental loss of those files in
   upgrade scenarios that we haven't yet thought of. If we had done this
   before, #1065022 would not have happened.

2. #1110825. Compiling language bindings against libgirepository-2.0-dev
   would generate dependencies that do not indicate which libffi ABI
   they assume, resulting in some broken combinations being allowed by
   dependencies during the next libffi transition. In practice I believe
   there are not yet any packages in trixie, forky or sid that use
   libgirepository-2.0-dev: gjs, pygobject, etc. are still using
   libgirepository-1.0-dev, except in experimental.
   I addressed this by forward-porting how we handle this in
   libgirepository-1.0-dev (part of src:gobject-introspection).
   If we can fix this before anything uses libgirepository-2.0-dev in
   production, then the next libffi transition won't need sourceful
   uploads of glib2.0 and can most likely be done via binNMUs.

3. The autopkgtest for future bugs related to #1065022 had regressed and
   no longer works. This is mostly harmless (it's marked as flaky anyway)
   but fixing it improves confidence that #1065022 has been handled
   and will not come back.

4. Upstream: #1110640 (CVE-2025-7039), a no-dsa CVE that I believe is not
   exploitable in practice. It would be good to have it fixed in case
   I'm wrong.

5. Upstream: a new upstream bugfix release which came too late to be
   included in 13.0. Nothing hugely urgent but the fixes would be good
   to have; in particular there might be apps/language bindings that
   expect g_settings_bind_with_mapping_closures() to work as documented.

[ Tests ]

In general: autopkgtests are relatively extensive and all pass, my GNOME 
laptop still works normally with the functionally equivalent version in 
sid, and a GNOME desktop still works with the proposed version for 
trixie.

An almost-functionally-equivalent version has been in unstable since 
2025-08-12 with no regressions reported by users. There was one known 
regression in the initial upload, fixed a few days later after I noticed 
it while preparing this trixie-pu: packages compiled against the new 
libgirepository-2.0-dev would be uninstallable, because I forgot to add 
the necessary Provides (now fixed in unstable and in this proposed 
update). But in practice that never affected anything outside experimental.

We saw an autopkgtest regression on i386 only (#1111373, a program that 
was statically linked to GLib segfaulting during startup) but I can't 
reproduce it, and now neither can ci.debian.net.

For the specific changes:

1. Manually tested: I updated the included manual test script
   debian/tests/manual/1065022.sh to also reproduce #1110696 when run
   with argument "1110696", and ran it with that argument.
   As expected, it failed with current trixie and succeeded with the
   proposed version.

   I also expanded the same script to exercise other improvements to the
   safety of the postrm: it now asserts that the generated files are
   correctly deleted during purge, except that when run with argument
   "extra-schema" or "extra-module", it creates an additional,
   unpackaged GSettings schema or GIO module before purge, and asserts
   that in this case the generated file is *not* deleted.

   To verify:
   - put proposed trixie packages in /path/to/proposed/debs
     (both amd64 and i386 are required)
   - "dpkg-scanpackages --multiversion . > Packages" in that directory
   - podman run --rm -it \
         -v /path/to/glib:/mnt/glib:ro -w /mnt/glib \
         -v /path/to/proposed/debs:/mnt/trixie:ro \
         debian:bookworm-slim debian/tests/manual/1065022.sh
   - then repeat with argument "1110696"
   - then repeat with argument "extra-schema" instead
   - then repeat with argument "extra-module" instead
   - in each case exit status should be 0
     (last line on stderr is "+ exit 0")

2. Not tested in the trixie version because there is nothing in trixie
   that would exercise it, but I rebuilt pygobject/experimental locally
   against the version in unstable, and it generates dependencies on
   the new virtual package libgirepository-2.0-0-with-libffi8 as
   expected (and this time they are satisfiable).

3. I ran the updated autopkgtest on amd64 in autopkgtest-virt-qemu and
   autopkgtest-virt-lxc, and it passes.

4. No specific test coverage, only the upstream test suite.

5. No specific test coverage, only the upstream test suite.

[ Risks ]

It's a key package in all desktop environments.

Essentially all changes are targeted at fixing specific bugs. The 
changes for #1110696 are not strictly minimal, but I tried to make them 
as easy as possible to review, even where that increased the diffstat a 
little.

The preinst is (still) doing out-of-spec things to go behind dpkg's back 
and disarm a faulty postrm in an earlier GLib version (as agreed with 
the technical committee on #1065170), so it does need some care.

We don't know why the unreproducible regression #1111373 happened on 
i386, or why it stopped happening. Mitigation: if it recurs, it will 
primarily affect qemu-user:i386 (the only statically linked GLib 
executables that I know about), and I don't think that package is 
frequently-used, particularly now that i386 is officially only for 
compatibility with legacy binaries.

The changes for #1110825 are a bit noisy, but it's still relatively 
narrowly targeted, would give us better confidence that the next libffi 
transition can be done via binNMUs, and as far as I can see nothing in 
trixie depends on the affected binary packages yet. I'm proposing to 
include this change because it would ensure that we don't need Breaks on 
any future trixie backports that might add this dependency.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [~] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

The attached diff is a git diff rather than a debdiff, to minimize the 
noise caused by renaming libgirepository-2.0-0.symbols to 
libgirepository-2.0-0.symbols.in. I intend to upload using dgit, which 
will guarantee that the .dsc exactly matches the tree that is in the git 
repo.

[ Changes ]

The only changes vs. unstable are in debian/tests/manual/1065022.sh and 
metadata (d/changelog, d/control Vcs-Git, d/gbp.conf debian-branch); the 
code that runs on end-user systems is the same as in unstable.

Changes since trixie, broken up by topic (see [ Reason / Impact ] above):

1. #1110696
   - d/libglib2.0-0t64.preinst: the actual bug fix; expand cleanup of
     the faulty postrm in bookworm to delete more instances
   - d/libglib2.0-0t64.postrm: preemptively avoid having this class of
     problem in future by being more careful not to delete files that
     might still be needed, while trying to make the new script as
     obviously-correct as possible
   - d/libglib2.0-0t64.postinst: silence shellcheck warnings
     (I was using shellcheck to try to make sure the maintainer
     scripts don't have real issues; no functional change in practice)
   - d/tests/manual/1065022.sh: Expand manual test script to exercise
     the related bug #1110696 as well as #1065022. This script is not
     included in any .deb or run automatically.

2. #1110825:
   - d/extra-substvars.py, heavily based on the script of the same name
     in src:gobject-introspection
   - d/control: emit a versioned Provides in libgirepository-2.0-0 to
     indicate what libffi ABI it is working with
   - d/control: B-D on python3-debian:native, for that script
   - libgirepository-2.0-0.symbols{,.in}: rename and edit to be
     processed by d/rules, generating dependencies on the virtual
     package if and only if a libffi-related symbol was used
   - d/rules: generate libgirepository-2.0-0.symbols from .in
   - d/clean: clean up the generated files

3. All changes in debian/tests/1065022-futureproofing

4. Upstream changes in glib/gfileutils.c

5. All other upstream changes

[ Other info ]

This will need a d-i ack for libglib2.0-udeb.
diff --git a/NEWS b/NEWS
index 192c29dbfb..b0d897e6e5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,24 @@
+Overview of changes in GLib 2.84.4, 2025-08-08
+==============================================
+
+* Bugs fixed:
+  - #3716 (CVE-2025-7039) (#YWH-PGM9867-104) Buffer Under-read on GLib through
+    glib/gfileutils.c via get_tmp_file() (Michael Catanzaro)
+  - #3721 GFile leak in g_local_file_set_display_name during error handling
+    (Philip Withnall, Michael Catanzaro)
+  - !4668 Backport !4667 “Incorrect output parameter handling in closure helper
+    of g_settings_bind_with_mapping_closures” to glib-2-84
+  - !4675 Backport !4674 “gfileutils: fix computation of temporary file name” to
+    glib-2-84
+  - !4679 Backport !4677 and !4678 “Fix GFile leak in
+    g_local_file_set_display_name()” to glib-2-84
+  - !4697 Backport !4696 “gthreadpool: Catch pool_spawner creation failure” to
+    glib-2-84
+  - !4705 Backport !4702 “gio/filenamecompleter: Fix leaks” to glib-2-84
+  - !4711 Backport !4708 “gfilenamecompleter: Fix g_object_unref() of undefined
+    value” to glib-2-84
+
+
 Overview of changes in GLib 2.84.3, 2025-06-13
 ==============================================
 
diff --git a/debian/changelog b/debian/changelog
index 7207a96974..982cbafac0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,78 @@
+glib2.0 (2.84.4-3~deb13u1) trixie; urgency=medium
+
+  * Go back to debian/trixie branch for a stable update
+  * d/tests/manual/1065022.sh: Update manual test script used to reproduce
+    and test fixes for #1065022
+    - Adapt to upgrade from bookworm to trixie, rather than bookworm to sid
+    - Optionally reproduce #1110696 instead
+    - Optionally test the extra safety checks in the postrm
+    - Add a simpler mechanism to test proposed packages for either
+      bookworm or trixie
+    - Improve diagnostic output
+
+ -- Simon McVittie <smcv@debian.org>  Mon, 18 Aug 2025 09:30:17 +0100
+
+glib2.0 (2.84.4-3) unstable; urgency=medium
+
+  * d/control: Generate the intended Provides in libgirepository-2.0-0
+
+ -- Simon McVittie <smcv@debian.org>  Sun, 17 Aug 2025 17:30:44 +0100
+
+glib2.0 (2.84.4-2) unstable; urgency=medium
+
+  * Mention #1110640 in previous changelog entry
+  * libgirepository-2.0-0: Generate a dependency on a virtual package
+    for libffi-related symbols, to avoid trouble during future libffi ABI
+    transitions (Closes: #1110825)
+  * libglib2.0-0t64: Make maintainer scripts shellcheck-clean
+  * libglib2.0-0t64.postrm:
+    - Refactor to use functions that early-return if we do not want to
+      do the cleanup, avoiding stacking conditionals
+    - Don't remove cache files if they would be non-empty,
+      guarding against issues similar to #1065022 and #1110696
+      (mitigates: #1110696)
+  * libglib2.0-0t64.preinst: Disarm libglib2.0-0 postrm for all
+    architectures, avoiding a corner case where the faulty postrm that
+    suffered from #1065022 would still exist if it belonged to a former
+    foreign architecture that was already disabled, but libglib2.0-0
+    from that architecture was still in removed-but-not-purged state,
+    resulting in #1065022 recurring when that version of libglib2.0-0
+    was subsequently purged (Closes: #1110696)
+  * d/tests/1065022-futureproofing:
+    - Fix a test regression by generating a versioned Provides when
+      building a mockup of a hypothetical future libglib2.0-0xyz.
+      This regression wasn't immediately obvious because the autopkgtest
+      is marked as flaky (it depends on various implementation details
+      which we can't completely rely on).
+    - Make sure required packages stay installed, failing the test early
+      if their dependencies cannot be satisfied
+    - Produce only TAP output on stdout, and a diagnostic log on stderr
+    - Improve diagnostic output
+
+ -- Simon McVittie <smcv@debian.org>  Tue, 12 Aug 2025 10:01:06 +0100
+
+glib2.0 (2.84.4-1) unstable; urgency=medium
+
+  * d/control, d/gbp.conf: Use debian/forky packaging branch.
+    The debian/latest branch is now tracking 2.85.x for Debian
+    experimental.
+  * New upstream stable release
+    - Ensure that generating temporary file names does not access memory
+      outside the intended array of alphanumeric characters if a long-running
+      program generates billions of temporary file names
+      (CVE-2025-7039, glib#3716 upstream; believed to be unlikely to be
+      exploitable in practice. Closes: #1110640)
+    - Fix the intended ability for g_settings_bind_with_mapping_closures()
+      to copy a value to the destination object
+      (glib!4667 upstream)
+    - If creating a thread pool fails, report a recoverable error instead
+      of crashing with a fatal error
+      (glib#3712 upstream)
+    - Fix several memory leaks
+      (glib#3721, glib!4702 upstream)
+
+ -- Simon McVittie <smcv@debian.org>  Fri, 08 Aug 2025 19:13:23 +0100
+
 glib2.0 (2.84.3-1) unstable; urgency=medium
 
   * New upstream stable release
diff --git a/debian/clean b/debian/clean
index 550447d14b..c0ad4464ee 100644
--- a/debian/clean
+++ b/debian/clean
@@ -1,4 +1,6 @@
 debian/cross-tools/
+debian/extra-substvars
+debian/libgirepository-2.0-0.symbols
 debian/libglib2.0-0t64.triggers
 debian/meson/exe-wrapper.ini
 gio/gdbus-2.0/codegen/*.pyc
diff --git a/debian/control b/debian/control
index 22ecdabc83..59fe1e5c83 100644
--- a/debian/control
+++ b/debian/control
@@ -26,6 +26,7 @@ Build-Depends:
  linux-libc-dev [linux-any],
  meson (>= 1.4.0),
  pkgconf,
+ python3-debian:native,
  python3-docutils <!nodoc>,
  python3-packaging:native,
  python3:native,
@@ -51,7 +52,7 @@ Rules-Requires-Root: no
 Standards-Version: 4.7.0
 Homepage: https://gitlab.gnome.org/GNOME/glib
 Vcs-Browser: https://salsa.debian.org/gnome-team/glib
-Vcs-Git: https://salsa.debian.org/gnome-team/glib.git
+Vcs-Git: https://salsa.debian.org/gnome-team/glib.git -b debian/trixie
 
 Package: libglib2.0-0t64
 Replaces:
@@ -379,6 +380,8 @@ Multi-Arch: same
 Depends:
  ${misc:Depends},
  ${shlibs:Depends},
+Provides:
+ libgirepository-2.0-0-with-${local:libffiN} (= ${binary:Version}),
 Description: GLib runtime library for handling GObject introspection data
  GLib is a library containing many useful C routines for things such
  as trees, hashes, lists, and strings.  It is a useful general-purpose
diff --git a/debian/extra-substvars.py b/debian/extra-substvars.py
new file mode 100755
index 0000000000..d6b743b2a6
--- /dev/null
+++ b/debian/extra-substvars.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python3
+# Copyright 2021 Simon McVittie
+# SPDX-License-Identifier: MIT
+
+'''
+Inspect libffi-dev:$DEB_HOST_ARCH and print the corresponding library ABI
+name, e.g. "local:libffiN=libffi8".
+'''
+
+import os
+import subprocess
+
+import debian.deb822
+
+if __name__ == '__main__':
+    deb_host_arch = os.environ['DEB_HOST_ARCH']
+
+    result = subprocess.run(
+        ['dpkg-query', '-s', 'libffi-dev:' + deb_host_arch],
+        stdout=subprocess.PIPE,
+        check=True,
+    )
+    stanza = result.stdout.decode('utf-8')      # type: ignore
+    fields = debian.deb822.Packages(stanza)
+
+    libffiN = ''
+
+    for dependency in fields.relations['depends']:
+        for alternative in dependency:
+            if (
+                alternative['name'].startswith('libffi')
+                and alternative['name'][6].isdigit()
+            ):
+                if libffiN != '':
+                    raise AssertionError(
+                        'More than one libffiN dependency in libffi-dev'
+                    )
+
+                libffiN = alternative['name']
+
+    if not libffiN:
+        raise AssertionError(
+            'No libffiN dependency in libffi-dev'
+        )
+
+    print('local:libffiN=' + libffiN)
+
+    for suffix in ('GNU_TYPE',):
+        var = 'DEB_HOST_' + suffix
+        substvar = var.replace('_', '-')
+        print(f'local:{substvar}={os.environ[var]}')
diff --git a/debian/gbp.conf b/debian/gbp.conf
index e5bd40a6df..61981bdf27 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,6 +1,6 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/latest
+debian-branch = debian/trixie
 upstream-branch = upstream/2.84.x
 component = unicode-data
 
diff --git a/debian/libgirepository-2.0-0.symbols b/debian/libgirepository-2.0-0.symbols.in
similarity index 93%
rename from debian/libgirepository-2.0-0.symbols
rename to debian/libgirepository-2.0-0.symbols.in
index 4ade1aafd4..32fac9ad15 100644
--- a/debian/libgirepository-2.0-0.symbols
+++ b/debian/libgirepository-2.0-0.symbols.in
@@ -1,4 +1,7 @@
+# Dependency template 0: ordinary symbols
 libgirepository-2.0.so.0 libgirepository-2.0-0 #MINVER#
+# Dependency template 1: symbols whose meaning depends on libffi ABI
+| libgirepository-2.0-0 #MINVER#, libgirepository-2.0-0-with-@libffiN@ #MINVER#
 * Build-Depends-Package: libgirepository-2.0-dev
  gi_arg_info_get_closure_index@Base 2.79.2
  gi_arg_info_get_destroy_index@Base 2.79.2
@@ -26,12 +29,12 @@ libgirepository-2.0.so.0 libgirepository-2.0-0 #MINVER#
  gi_base_info_ref@Base 2.79.2
  gi_base_info_unref@Base 2.79.2
  gi_callable_info_can_throw_gerror@Base 2.79.2
- gi_callable_info_create_closure@Base 2.79.2
- gi_callable_info_destroy_closure@Base 2.79.2
+ gi_callable_info_create_closure@Base 2.79.2 1
+ gi_callable_info_destroy_closure@Base 2.79.2 1
  gi_callable_info_get_arg@Base 2.79.2
  gi_callable_info_get_async_function@Base 2.83.0
  gi_callable_info_get_caller_owns@Base 2.79.2
- gi_callable_info_get_closure_native_address@Base 2.79.2
+ gi_callable_info_get_closure_native_address@Base 2.79.2 1
  gi_callable_info_get_finish_function@Base 2.83.0
  gi_callable_info_get_instance_ownership_transfer@Base 2.79.2
  gi_callable_info_get_n_args@Base 2.79.2
@@ -74,9 +77,9 @@ libgirepository-2.0.so.0 libgirepository-2.0-0 #MINVER#
  gi_function_info_get_type@Base 2.79.2
  gi_function_info_get_vfunc@Base 2.79.2
  gi_function_info_invoke@Base 2.79.2
- gi_function_info_prep_invoker@Base 2.79.2
- gi_function_invoker_clear@Base 2.79.2
- gi_function_invoker_new_for_address@Base 2.79.2
+ gi_function_info_prep_invoker@Base 2.79.2 1
+ gi_function_invoker_clear@Base 2.79.2 1
+ gi_function_invoker_new_for_address@Base 2.79.2 1
  gi_interface_info_find_method@Base 2.79.2
  gi_interface_info_find_signal@Base 2.79.2
  gi_interface_info_find_vfunc@Base 2.79.2
@@ -186,11 +189,11 @@ libgirepository-2.0.so.0 libgirepository-2.0-0 #MINVER#
  gi_struct_info_is_foreign@Base 2.79.2
  gi_struct_info_is_gtype_struct@Base 2.79.2
  gi_type_info_argument_from_hash_pointer@Base 2.79.2
- gi_type_info_extract_ffi_return_value@Base 2.79.2
+ gi_type_info_extract_ffi_return_value@Base 2.79.2 1
  gi_type_info_get_array_fixed_size@Base 2.79.2
  gi_type_info_get_array_length_index@Base 2.79.2
  gi_type_info_get_array_type@Base 2.79.2
- gi_type_info_get_ffi_type@Base 2.79.2
+ gi_type_info_get_ffi_type@Base 2.79.2 1
  gi_type_info_get_interface@Base 2.79.2
  gi_type_info_get_param_type@Base 2.79.2
  gi_type_info_get_storage_type@Base 2.79.2
@@ -200,8 +203,8 @@ libgirepository-2.0.so.0 libgirepository-2.0-0 #MINVER#
  gi_type_info_is_pointer@Base 2.79.2
  gi_type_info_is_zero_terminated@Base 2.79.2
  gi_type_tag_argument_from_hash_pointer@Base 2.79.2
- gi_type_tag_extract_ffi_return_value@Base 2.79.2
- gi_type_tag_get_ffi_type@Base 2.79.2
+ gi_type_tag_extract_ffi_return_value@Base 2.79.2 1
+ gi_type_tag_get_ffi_type@Base 2.79.2 1
  gi_type_tag_hash_pointer_from_argument@Base 2.79.2
  gi_type_tag_to_string@Base 2.79.2
  gi_typelib_get_namespace@Base 2.79.2
diff --git a/debian/libglib2.0-0t64.postinst b/debian/libglib2.0-0t64.postinst
index d140c17646..0d9da799b6 100644
--- a/debian/libglib2.0-0t64.postinst
+++ b/debian/libglib2.0-0t64.postinst
@@ -1,13 +1,15 @@
 #!/bin/sh
+# Debian Policy §10.4 says /bin/sh has a superset of POSIX functionality
+# shellcheck disable=SC3043
+
 set -e
 
 
 handle_triggers () {
     local trigger
-    local dirs
 
     for trigger in "$@"; do
-        if ! [ -d $trigger ]; then
+        if ! [ -d "$trigger" ]; then
             continue
         fi
         case $trigger in
@@ -28,6 +30,8 @@ handle_triggers () {
 }
 
 if [ "$1" = triggered ]; then
+    # The list of triggers is space-separated, so word-splitting is intended:
+    # shellcheck disable=SC2086
     handle_triggers $2
     exit 0
 fi
diff --git a/debian/libglib2.0-0t64.postrm b/debian/libglib2.0-0t64.postrm
index 056e982134..e8f0819e0d 100644
--- a/debian/libglib2.0-0t64.postrm
+++ b/debian/libglib2.0-0t64.postrm
@@ -1,34 +1,87 @@
 #! /bin/sh
+# Debian Policy §10.4 says /bin/sh has a superset of POSIX functionality
+# shellcheck disable=SC3043
+
 set -e
 
 #DEBHELPER#
 
+clean_up_giomodule_cache ()
+{
+    local multiarch="#DEB_HOST_MULTIARCH#"
+    local modules="/usr/lib/${multiarch}/gio/modules"
+    local iter
+
+    if ! [ -d "$modules" ]; then
+        return 0
+    fi
+
+    # Don't remove giomodule.cache if libglib2.0-0t64 has been replaced
+    # by some other ABI variant of essentially the same library
+    # (for example libglib2.0-0xyz), if that ever happens, to
+    # avoid causing an equivalent of <https://bugs.debian.org/1065022>.
+    #
+    # This implementation is based on the assumption that any GLib
+    # version that still uses ${libdir}/gio/modules/giomodule.cache
+    # will also continue to ship ${libdir}/glib-2.0.
+    if [ -d "/usr/lib/${multiarch}/glib-2.0" ]; then
+        return 0
+    fi
+
+    # As an additional safety-catch, don't remove giomodule.cache if
+    # there is at least one module that should have been listed in it.
+    for iter in "$modules"/*.so; do
+        if [ -e "$iter" ]; then
+            echo "$0: not removing $modules/giomodule.cache because $iter still exists" >&2
+            return 0
+        fi
+    done
+
+    rm -f "$modules/giomodule.cache"
+    rmdir -p --ignore-fail-on-non-empty "$modules"
+}
+
+clean_up_gsettings_schemas ()
+{
+    local schemas="/usr/share/glib-2.0/schemas"
+    local iter
+
+    if ! [ -d "$schemas" ]; then
+        return 0
+    fi
+
+    # Similarly, instead of using $DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT, only
+    # remove gschemas.compiled if GLib has completely gone away - not just
+    # libglib2.0-0 and libglib2.0-0t64, but any possible future ABI variant
+    # like libglib2.0-0xyz.
+    #
+    # This implementation is based on the assumption that any GLib
+    # version that still uses ${datadir}/glib-2.0/schemas
+    # will also continue to ship ${libdir}/glib-2.0.
+    for iter in /usr/lib/*/glib-2.0; do
+        if [ -e "$iter" ]; then
+            return 0
+        fi
+    done
+
+    # As an additional safety-catch, don't remove gschemas.compiled if
+    # there is at least one schema that should have been listed in it.
+    for iter in "$schemas"/*.xml; do
+        if [ -e "$iter" ]; then
+            echo "$0: not removing $schemas/gschemas.compiled because $iter still exists" >&2
+            return 0
+        fi
+    done
+
+    rm -f "$schemas/gschemas.compiled"
+    rmdir -p --ignore-fail-on-non-empty "$schemas"
+}
+
 case "$1" in
     (purge)
-        # Don't remove giomodule.cache if libglib2.0-0t64 has been replaced
-        # by some other ABI variant of essentially the same library
-        # (for example libglib2.0-0xyz), if that ever happens, to
-        # avoid causing an equivalent of <https://bugs.debian.org/1065022>.
-        #
-        # This implementation is based on the assumption that any GLib
-        # version that still uses ${libdir}/gio/modules/giomodule.cache
-        # will also continue to ship ${libdir}/glib-2.0.
-        if [ -d /usr/lib/#DEB_HOST_MULTIARCH#/gio/modules ] && ! [ -d "/usr/lib/#DEB_HOST_MULTIARCH#/glib-2.0" ]; then
-            rm -f /usr/lib/#DEB_HOST_MULTIARCH#/gio/modules/giomodule.cache
-            rmdir -p --ignore-fail-on-non-empty /usr/lib/#DEB_HOST_MULTIARCH#/gio/modules
-        fi
+        clean_up_giomodule_cache
+        clean_up_gsettings_schemas
         ;;
 esac
 
-# Similarly, instead of using $DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT, only
-# remove gschemas.compiled if GLib has completely gone away - not just
-# libglib2.0-0 and libglib2.0-0t64, but any possible future ABI variant
-# like libglib2.0-0xyz.
-#
-# This implementation is based on the assumption that any GLib
-# version that still uses ${datadir}/glib-2.0/schemas
-# will also continue to ship ${libdir}/glib-2.0.
-if [ "$1" = purge ] && [ -d /usr/share/glib-2.0/schemas ] && [ "$(echo /usr/lib/*/glib-2.0)" = "/usr/lib/*/glib-2.0" ]; then
-    rm -f /usr/share/glib-2.0/schemas/gschemas.compiled
-    rmdir -p --ignore-fail-on-non-empty /usr/share/glib-2.0/schemas
-fi
+# vim:set sw=4 sts=4 et:
diff --git a/debian/libglib2.0-0t64.preinst b/debian/libglib2.0-0t64.preinst
index cd55739e43..f76c4f334b 100644
--- a/debian/libglib2.0-0t64.preinst
+++ b/debian/libglib2.0-0t64.preinst
@@ -13,12 +13,12 @@ set -e
 case "$1" in
     (install|upgrade)
         # Do this cleanup on upgrade from any version older than the one that
-        # introduced this change to experimental.
+        # addressed #1110696.
         #
         # We also need to do this cleanup on new installations of
         # libglib2.0-0t64 (because any new installation might be replacing
         # libglib2.0-0) so treat an empty version as being arbitrarily old.
-        if dpkg --compare-versions "${2:-}" lt "2.79.3-3"
+        if dpkg --compare-versions "${2:-}" lt "2.84.4-2~"
         then
             # If there are several multiarch instances, they might have been
             # removed but not purged, in which case purging them (perhaps
@@ -28,7 +28,12 @@ case "$1" in
             # only doing this cleanup for the current architecture, we attempt
             # to clean up all multiarch instances the first time any single
             # instance is installed or upgraded.
-            for arch in $(dpkg --print-architecture) $(dpkg --print-foreign-architectures)
+            # This originally used $(dpkg --print-architecture) and
+            # $(dpkg --print-foreign-architectures), but it is possible for
+            # libglib2.0-0:i386 to still exist in removed-but-not-purged
+            # state after an i386 foreign architecture has been disabled:
+            # see #1110696.
+            for arch in $(dpkg-query -W -f '${Architecture}\n' libglib2.0-0 2>/dev/null || true)
             do
                 if old_postrm=$(dpkg-query --control-path "libglib2.0-0:$arch" postrm 2>/dev/null) \
                     && [ -n "$old_postrm" ] \
diff --git a/debian/rules b/debian/rules
index 8e1fdc93ee..e0e42eba4f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -62,6 +62,9 @@ maintainer-update-unicode-data:
 	rm -f glib/tests/casemap.txt
 	$(CURDIR)/tools/update-unicode-data.sh $(CURDIR)/unicode-data 16.0.0
 
+debian/extra-substvars:
+	dpkg-architecture -c debian/extra-substvars.py > debian/extra-substvars
+
 execute_before_dh_auto_configure: cross-tools
 
 cross_tools = \
@@ -407,7 +410,12 @@ execute_before_dh_installdeb-arch:
 		    > debian/libglib2.0-0t64.$$script ; \
 	done
 
-override_dh_gencontrol-arch:
-	dh_gencontrol -pgirepository-tools -- \
-		-Vlocal:DEB-HOST-GNU-TYPE=$(DEB_HOST_GNU_TYPE)
-	dh_gencontrol --remaining-packages
+debian/libgirepository-2.0-0.symbols: debian/libgirepository-2.0-0.symbols.in debian/extra-substvars
+	set -e; \
+	libffiN=$$(sed -ne 's/^local:libffiN=//p' debian/extra-substvars); \
+	sed -e "s/@libffiN@/$$libffiN/" < $< > $@
+
+execute_before_dh_makeshlibs: debian/libgirepository-2.0-0.symbols
+
+override_dh_gencontrol: debian/extra-substvars
+	dh_gencontrol -- -Tdebian/extra-substvars
diff --git a/debian/tests/1065022-futureproofing b/debian/tests/1065022-futureproofing
index d84a423365..d1dec80ef4 100755
--- a/debian/tests/1065022-futureproofing
+++ b/debian/tests/1065022-futureproofing
@@ -17,13 +17,16 @@ srcdir="$(pwd)"
 tmpdir="$(mktemp -d)"
 cd "$tmpdir"
 
+# Machine-readable TAP on fd 3, human-readable diagnostics on fds 1 and 2
+exec 3>&1 >&2
+
 assert () {
     n=$(( n + 1 ))
 
     if "$@"; then
-        echo "ok $n - $*"
+        echo "ok $n - $*" >&3
     else
-        echo "not ok $n - $* exit status $?"
+        echo "not ok $n - $* exit status $?" >&3
         failed=1
     fi
 }
@@ -32,9 +35,9 @@ assert_not () {
     n=$(( n + 1 ))
 
     if ! "$@"; then
-        echo "ok $n - unsuccessful as expected: $*"
+        echo "ok $n - unsuccessful as expected: $*" >&3
     else
-        echo "not ok $n - should not have succeeded: $*"
+        echo "not ok $n - should not have succeeded: $*" >&3
         failed=1
     fi
 }
@@ -56,6 +59,10 @@ fi
 # This assumes that libglib2.0-0t64 has at least one each of Breaks, Provides
 # and Replaces, and will need to be adjusted if that assumption is broken in
 # the future for whatever reason.
+dpkg-query -s "$binary_package"
+# The $ substitution is to be expanded by dpkg-query:
+# shellcheck disable=SC2016
+binary_version="$(dpkg-query -W -f '${Version}' "$binary_package")"
 dpkg-repack --generate "$binary_package"
 grep -q '^Breaks:' dpkg-repack.*/DEBIAN/control
 grep -q '^Provides:' dpkg-repack.*/DEBIAN/control
@@ -65,15 +72,18 @@ grep -q '^Replaces:' dpkg-repack.*/DEBIAN/control
 # shellcheck disable=SC2016
 env \
     binary_package="$binary_package" \
+    binary_version="$binary_version" \
     future_binary_package="$future_binary_package" \
     perl -p -i \
         -e 's/^Package:.*$/Package: $ENV{future_binary_package}/;' \
         -e 's/^(Breaks:.*)$/$1, $ENV{binary_package}/;' \
-        -e 's/^(Provides:.*)$/$1, $ENV{binary_package}/;' \
+        -e 's/^(Provides:.*)$/$1, $ENV{binary_package} (= $ENV{binary_version})/;' \
         -e 's/^(Replaces:.*)$/$1, $ENV{binary_package}/;' \
         dpkg-repack.*/DEBIAN/control
 dpkg-deb --build dpkg-repack.* "$future_binary_package.deb"
-apt-get -y install ./"$future_binary_package.deb"
+dpkg-deb --info "$future_binary_package.deb"
+dpkg-deb --contents "$future_binary_package.deb"
+apt-get -y install ./"$future_binary_package.deb" dconf-gsettings-backend gsettings-desktop-schemas
 
 assert test -e /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml
 assert test -s /usr/share/glib-2.0/schemas/gschemas.compiled
@@ -120,7 +130,7 @@ for f in /usr/lib/*/gio/modules/giomodule.cache; do
     assert_not test -e "$f"
 done
 
-echo "1..$n"
+echo "1..$n" >&3
 exit "$failed"
 
 # vim:set sw=4 sts=4 et:
diff --git a/debian/tests/manual/1065022.sh b/debian/tests/manual/1065022.sh
index 6330eb751d..6aaf7ec201 100755
--- a/debian/tests/manual/1065022.sh
+++ b/debian/tests/manual/1065022.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2024 Simon McVittie
+# Copyright 2024-2025 Simon McVittie
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 # Reproducer for <https://bugs.debian.org/1065022>.
@@ -8,6 +8,19 @@
 # libglib2.0-0, for example:
 # podman run --rm -it -v $(pwd):$(pwd):ro -w $(pwd) debian:bookworm-slim debian/tests/manual/1065022.sh
 # podman run --rm -it -v $(pwd):$(pwd):ro -w $(pwd) debian:sid-20240110-slim debian/tests/manual/1065022.sh
+#
+# To test proposed packages for bookworm and/or trixie, generate a
+# Packages file in the directory with the packages
+# (dpkg-scanpackages --multiversion . > Packages)
+# and add
+# -v /proposed-bookworm-debs-here:/mnt/bookworm:ro
+# -v /proposed-trixie-debs-here:/mnt/trixie:ro
+# to the podman command-line.
+#
+# Optional argument:
+# - 1110696 to reproduce <https://bugs.debian.org/1110696>
+# - extra-schema or extra-module to exercise additional safety check added
+#   while fixing <https://bugs.debian.org/1110696>
 
 set -eux
 
@@ -29,6 +42,12 @@ assert () {
     fi
 }
 
+# Add a deb822-formatted apt source at this location if you are testing a
+# locally-built glib2.0 for bookworm before upload
+if [ -e /mnt/bookworm/Packages ]; then
+    echo "deb [trusted=yes] file:///mnt/bookworm ./" > /etc/apt/sources.list.d/proposed.list
+fi
+
 # Preconditions: install libglib2.0-0, libglib2.0-0t64, at least one
 # GSettings schema and at least one GIO module.
 dpkg --add-architecture "$other_arch"
@@ -51,29 +70,39 @@ for tuple in "$this_tuple" "$other_tuple"; do
     test -s "$f"
 done
 
+# Make it visible what the postrm is doing
+sed -i -e 's/^set -e$/&x/g' /var/lib/dpkg/info/libglib2.0-0*.postrm || true
+
 # Remove but do not purge the other architecture's packages
 apt-get -y remove "libglib2.0-0:$other_arch" "dconf-gsettings-backend:$other_arch"
 apt-get -y autoremove
 
-# Upgrade to current unstable, with libglib2.0-0t64
+if [ "${1-}" = 1110696 ]; then
+    # To reproduce #1110696, completely remove the other architecture
+    apt-get -y remove --allow-remove-essential $(dpkg-query -W -f '${binary:Package}\n' | grep :i386)
+    dpkg --remove-architecture i386
+fi
+
+# Upgrade to trixie with libglib2.0-0t64
 cat > /etc/apt/sources.list.d/debian.sources <<EOF
 Types: deb
 URIs: http://deb.debian.org/debian
-Suites: sid
+Suites: trixie
 Components: main
 Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
 EOF
 
 # Add a deb822-formatted apt source at this location if you are testing a
 # locally-built glib2.0 before upload
-if [ -e "debian/tests/manual/local-1065022.sources" ]; then
-    install -m644 "debian/tests/manual/local-1065022.sources" /etc/apt/sources.list.d/
+if [ -e /mnt/trixie/Packages ]; then
+    echo "deb [trusted=yes] file:///mnt/trixie ./" > /etc/apt/sources.list.d/proposed.list
 fi
 
 # Reproducer (1): Upgrade to libglib2.0-0t64. This runs the postrm from
 # libglib2.0-0, which deletes necessary files.
 apt-get -y update
 apt-get -y install --purge libglib2.0-0t64
+sed -i -e 's/^set -e$/&x/g' /var/lib/dpkg/info/libglib2.0-0*.postrm || true
 
 assert test -e /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml
 assert test -s /usr/share/glib-2.0/schemas/gschemas.compiled
@@ -87,6 +116,7 @@ assert test -s "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
 # Workaround: Trigger the postinst of libglib2.0-0t64, which will regenerate
 # the generated files.
 apt-get -y install --reinstall libglib2.0-0t64
+sed -i -e 's/^set -e$/&x/g' /var/lib/dpkg/info/libglib2.0-0*.postrm || true
 
 assert test -e /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml
 assert test -s /usr/share/glib-2.0/schemas/gschemas.compiled
@@ -99,9 +129,11 @@ assert test -s "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
 
 # Reproducer (2): Purge the other multiarch instance of libglib2.0-0.
 # Again this runs the postrm from libglib2.0-0, which deletes necessary files.
+# (This is also the relevant part for reproducing #1110696.)
 dpkg --purge "libglib2.0-0:$other_arch"
 
 assert test -e /usr/share/glib-2.0/schemas/org.gnome.desktop.interface.gschema.xml
+# This is the assertion that will fail for #1110696
 assert test -s /usr/share/glib-2.0/schemas/gschemas.compiled
 
 assert test -e "/usr/lib/$this_tuple/gio/modules/libdconfsettings.so"
@@ -110,6 +142,47 @@ assert test -s "/usr/lib/$this_tuple/gio/modules/libdconfsettings.so"
 assert test -e "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
 assert test -s "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
 
+case "${1-}" in
+    (extra-schema)
+        touch "/usr/share/glib-2.0/schemas/UNPACKAGED.xml"
+        ;;
+    (extra-module)
+        touch "/usr/lib/$this_tuple/gio/modules/UNPACKAGED.so"
+        ;;
+esac
+
+# Merely removing GLib does not delete the generated files, although
+# they might have become empty.
+apt-get -y remove libglib2.0-0t64
+assert test -e /usr/share/glib-2.0/schemas/gschemas.compiled
+assert test -e "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
+
+# Purge GLib completely, taking dependent packages with it.
+apt-get -y remove --purge libglib2.0-0t64
+
+case "${1-}" in
+    (extra-schema)
+        # Because /usr/share/glib-2.0/schemas/UNPACKAGED.xml exists,
+        # we err on the side of caution and do not remove the compiled
+        # schemas.
+        assert test -e /usr/share/glib-2.0/schemas/gschemas.compiled
+        ;;
+    (*)
+        # Otherwise, we should remove it during purge.
+        assert test ! -e /usr/share/glib-2.0/schemas/gschemas.compiled
+        ;;
+esac
+
+# As above, but for GIO modules.
+case "${1-}" in
+    (extra-module)
+        assert test -e "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
+        ;;
+    (*)
+        assert test ! -e "/usr/lib/$this_tuple/gio/modules/giomodule.cache"
+        ;;
+esac
+
 echo "1..$n"
 exit "$failed"
 
diff --git a/gio/gfilenamecompleter.c b/gio/gfilenamecompleter.c
index 295ade05b2..795418cbc6 100644
--- a/gio/gfilenamecompleter.c
+++ b/gio/gfilenamecompleter.c
@@ -342,11 +342,13 @@ init_completion (GFilenameCompleter *completer,
 		 char **basename_out)
 {
   gboolean should_escape;
-  GFile *file, *parent;
+  GFile *file = NULL, *parent = NULL;
   char *basename;
   char *t;
   size_t len;
+  GList *basenames;
 
+  basenames = NULL;
   *basename_out = NULL;
   
   should_escape = ! (g_path_is_absolute (initial_text) || *initial_text == '~');
@@ -355,23 +357,20 @@ init_completion (GFilenameCompleter *completer,
   
   if (len > 0 &&
       initial_text[len - 1] == '/')
-    return NULL;
+    goto out;
   
   file = g_file_parse_name (initial_text);
   parent = g_file_get_parent (file);
   if (parent == NULL)
-    {
-      g_object_unref (file);
-      return NULL;
-    }
+    goto out;
 
   if (completer->basenames_dir == NULL ||
       completer->basenames_are_escaped != should_escape ||
       !g_file_equal (parent, completer->basenames_dir))
     {
       schedule_load_basenames (completer, parent, should_escape);
-      g_object_unref (file);
-      return NULL;
+
+      goto out;
     }
   
   basename = g_file_get_basename (file);
@@ -388,12 +387,17 @@ init_completion (GFilenameCompleter *completer,
       g_free (t);
       
       if (basename == NULL)
-	return NULL;
+        goto out;
     }
 
+  basenames = completer->basenames;
   *basename_out = basename;
 
-  return completer->basenames;
+out:
+  g_clear_object (&file);
+  g_clear_object (&parent);
+
+  return basenames;
 }
 
 /**
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index d9903b4e47..1e5c301542 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -1189,6 +1189,7 @@ g_local_file_set_display_name (GFile         *file,
       if (errsv != ENOENT)
         {
           g_set_io_error (error, _("Error renaming file %s: %s"), new_file, errsv);
+          g_object_unref (new_file);
           return NULL;
         }
     }
@@ -1196,6 +1197,7 @@ g_local_file_set_display_name (GFile         *file,
     {
       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
                            _("Can’t rename file, filename already exists"));
+      g_object_unref (new_file);
       return NULL;
     }
 
diff --git a/gio/gsettings.c b/gio/gsettings.c
index fbee36b3a3..628f8b572d 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -3161,6 +3161,14 @@ bind_with_mapping_invoke_get (GValue *value,
   g_closure_invoke (data->get_mapping_closure, &out, 2, params, /* hint = */ NULL);
 
   retval = g_value_get_boolean (&out);
+  if (retval)
+    {
+      const GValue *out_value = g_value_get_boxed (&params[0]);
+
+      g_assert (out_value != NULL);
+
+      g_value_copy (out_value, value);
+    }
 
   g_value_unset (&out);
   g_value_unset (&params[0]);
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index 60f2aebae8..69e92c051f 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -1827,6 +1827,7 @@ test_bind_with_mapping_closures_parameters (void)
   GSettings *settings;
   GClosure *get;
   GClosure *set;
+  gboolean val;
   BindWithMappingData data = { FALSE, FALSE, FALSE, FALSE };
 
   settings = g_settings_new ("org.gtk.test.binding");
@@ -1843,6 +1844,8 @@ test_bind_with_mapping_closures_parameters (void)
 
   g_assert_true (data.get_called);
   g_assert_false (data.set_called);
+  g_object_get (obj, "bool", &val, NULL);
+  g_assert_true (val);
 
   data.get_called = FALSE;
   g_object_set (obj, "bool", FALSE, NULL);
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index bc4bcf1f4d..9930030d25 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -1517,9 +1517,9 @@ get_tmp_file (gchar            *tmpl,
   static const char letters[] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
   static const int NLETTERS = sizeof (letters) - 1;
-  gint64 value;
-  gint64 now_us;
-  static int counter = 0;
+  guint64 value;
+  guint64 now_us;
+  static guint counter = 0;
 
   g_return_val_if_fail (tmpl != NULL, -1);
 
@@ -1538,7 +1538,7 @@ get_tmp_file (gchar            *tmpl,
 
   for (count = 0; count < 100; value += 7777, ++count)
     {
-      gint64 v = value;
+      guint64 v = value;
 
       /* Fill in the random bits.  */
       XXXXXX[0] = letters[v % NLETTERS];
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index 10fa2bceb3..e511102c38 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -582,6 +582,7 @@ g_thread_pool_new_full (GFunc           func,
 {
   GRealThreadPool *retval;
   G_LOCK_DEFINE_STATIC (init);
+  GError *local_error = NULL;
 
   g_return_val_if_fail (func, NULL);
   g_return_val_if_fail (!exclusive || max_threads != -1, NULL);
@@ -629,22 +630,19 @@ g_thread_pool_new_full (GFunc           func,
 
       spawn_thread_queue = g_async_queue_new ();
       g_cond_init (&spawn_thread_cond);
-      pool_spawner = g_thread_new ("pool-spawner", g_thread_pool_spawn_thread, NULL);
+      pool_spawner = g_thread_try_new ("pool-spawner", g_thread_pool_spawn_thread, NULL, &local_error);
       g_ignore_leak (pool_spawner);
     }
   G_UNLOCK (init);
 
-  if (retval->pool.exclusive)
+  if (retval->pool.exclusive && local_error == NULL)
     {
       g_async_queue_lock (retval->queue);
 
       while (retval->num_threads < (guint) retval->max_threads)
         {
-          GError *local_error = NULL;
-
           if (!g_thread_pool_start_thread (retval, &local_error))
             {
-              g_propagate_error (error, local_error);
               break;
             }
         }
@@ -652,6 +650,18 @@ g_thread_pool_new_full (GFunc           func,
       g_async_queue_unlock (retval->queue);
     }
 
+  if (local_error != NULL)
+    {
+      /* Failed to create pool spawner or failed to start a thread,
+       * so we must return NULL */
+      g_propagate_error (error, local_error);
+
+      g_clear_pointer (&retval->queue, g_async_queue_unref);
+      g_cond_clear (&retval->cond);
+
+      g_clear_pointer (&retval, g_free);
+    }
+
   return (GThreadPool*) retval;
 }
 
diff --git a/meson.build b/meson.build
index 2aff65bc02..8f3f686add 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('glib', 'c',
-  version : '2.84.3',
+  version : '2.84.4',
   # NOTE: See the policy in docs/meson-version.md before changing the Meson dependency
   meson_version : '>= 1.4.0',
   default_options : [

Reply to: