--- Begin Message ---
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: qemu@packages.debian.org, pkg-qemu-devel@lists.alioth.debian.org
Control: affects -1 + src:qemu
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package qemu
[ Reason ]
This upload fixes two issues which are important to fix before
the trixie release. It is the usage of future Static-Built-Using
instead of Built-Using for qemu-user (#1106804) - trivial fix.
And a use-after-free in qemu multi-threaded TCG mode (#1106792) -
a fix which took quite significant amount of resources to track
down, and affected multiple other packages in debian already.
Both of these fixes definitely should go to trixie.
There are two additional small fixes, - one is dropping a long-
irrelevant alternative in build-deps (needed for buster-backports),
and another is a simplification of too complex expression when
auto-generating package descriptions - it does not affect the
resulting packages, but makes this part of d/rules simpler.
Both these 2 small changes are of very low risk.
[ Impact ]
Built-Using field for #1106804 - currently, qemu-user package does
not meet the requiriments of the Debian Policy, so keeping it in
this way for release isn't the right thing to do.
The UAF fix for #1106792 - without it, qemu-system randomly crashes
in various configs, which affects multiple software, especially when
qemu is used for testing. It is also not the kind of issues we want
to keep in a release.
[ Tests ]
The main fix in this release, #1106792, while changes one of the more
important areas in qemu memory management, has been tested by multiple
people in several configurations, and reviewed. I don't expect additional
breakage from it.
Additional automatic tests are run while I'm submitting this report,
I'll reply to this bug report if anything fails. But I don't expect
any new failures.
[ Risks ]
Again, the main change (the fix for #1106792) is the only one which might
be risky. Hopefully we tested all interesting scenarious involving this
code.
Other changes are trivial and of very low risk.
[ 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
unblock qemu/1:10.0.2+ds-1
diff -Nru qemu-10.0.2+ds/debian/changelog qemu-10.0.2+ds/debian/changelog
--- qemu-10.0.2+ds/debian/changelog 2025-05-29 10:13:25.000000000 +0300
+++ qemu-10.0.2+ds/debian/changelog 2025-07-25 12:05:29.000000000 +0300
@@ -1,3 +1,17 @@
+qemu (1:10.0.2+ds-2) unstable; urgency=medium
+
+ * d/control: switch from Static-Built-Using
+ back to Built-Using for qemu-user (Closes: #1106804)
+ * d/rules: simplify qemu:archlist variable generation
+ (does not change the resulting packages)
+ * d/control: drop build dependency alternative on python3-tomli,
+ which was needed for bpo builds before bookworm (Closes: #1105938)
+ * system-physmem-fix-use-after-free-with-dispatch.patch long-awaited
+ fix for UAF which was affected multiple other packages and was quite
+ difficult to track (Closes: #1106792)
+
+ -- Michael Tokarev <mjt@tls.msk.ru> Fri, 25 Jul 2025 12:05:29 +0300
+
qemu (1:10.0.2+ds-1) unstable; urgency=medium
* new upstream stable/bugfix release:
diff -Nru qemu-10.0.2+ds/debian/control qemu-10.0.2+ds/debian/control
--- qemu-10.0.2+ds/debian/control 2025-05-29 10:13:25.000000000 +0300
+++ qemu-10.0.2+ds/debian/control 2025-07-25 12:05:29.000000000 +0300
@@ -7,7 +7,7 @@
Build-Depends: debhelper-compat (= 13),
python3:any,
python3-venv:any,
- python3:any (>> 3.11) | python3-tomli,
+ python3:any (>> 3.11),
meson (>> 1.5.0~), ninja-build,
flex, bison,
# for :native suffix see #995622
@@ -586,7 +586,7 @@
Package: qemu-user
Architecture: amd64 arm arm64 armel armhf i386 loong64 mips mips64 mips64el mipsel powerpc powerpcspe ppc64 ppc64el riscv64 s390x sparc sparc64
Multi-Arch: foreign
-Static-Built-Using: ${built-using}
+Built-Using: ${built-using}
Build-Profiles: <!pkg.qemu.omit-user>
Depends: ${misc:Depends}
Breaks: qemu-user-static (<< 1:9.1.0), qemu-user-binfmt (<< 1:9.1.0)
diff -Nru qemu-10.0.2+ds/debian/control-in qemu-10.0.2+ds/debian/control-in
--- qemu-10.0.2+ds/debian/control-in 2025-05-12 09:53:18.000000000 +0300
+++ qemu-10.0.2+ds/debian/control-in 2025-07-10 09:48:56.000000000 +0300
@@ -8,7 +8,7 @@
Build-Depends: debhelper-compat (= 13),
python3:any,
python3-venv:any,
- python3:any (>> 3.11) | python3-tomli,
+ python3:any (>> 3.11),
meson (>> 1.5.0~), ninja-build,
flex, bison,
# for :native suffix see #995622
@@ -640,7 +640,7 @@
Package: qemu-user
Architecture: :user-arch:
Multi-Arch: foreign
-Static-Built-Using: ${built-using}
+Built-Using: ${built-using}
Build-Profiles: <!pkg.qemu.omit-user>
Depends: ${misc:Depends}
Breaks: qemu-user-static (<< 1:9.1.0), qemu-user-binfmt (<< 1:9.1.0)
diff -Nru qemu-10.0.2+ds/debian/patches/series qemu-10.0.2+ds/debian/patches/series
--- qemu-10.0.2+ds/debian/patches/series 2025-05-29 09:31:43.000000000 +0300
+++ qemu-10.0.2+ds/debian/patches/series 2025-07-25 12:03:37.000000000 +0300
@@ -16,3 +16,4 @@
qemu-img-options.patch
disable-pycotap.patch
hw-display-qxl-render.c-fix-qxl_unpack_chunks-chunk-.patch
+system-physmem-fix-use-after-free-with-dispatch.patch
diff -Nru qemu-10.0.2+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch qemu-10.0.2+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch
--- qemu-10.0.2+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch 1970-01-01 03:00:00.000000000 +0300
+++ qemu-10.0.2+ds/debian/patches/system-physmem-fix-use-after-free-with-dispatch.patch 2025-07-25 12:03:24.000000000 +0300
@@ -0,0 +1,126 @@
+From: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Subject: system/physmem: fix use-after-free with dispatch
+Date: Thu, 24 Jul 2025 09:11:42 -0700
+Message-ID: <20250724161142.2803091-1-pierrick.bouvier@linaro.org>
+MIME-Version: 1.0
+Content-Transfer-Encoding: 8bit
+Bug-Debian: https://bugs.debian.org/1106792
+Origin: upstream, https://lore.kernel.org/qemu-devel/afddf3fc-5561-40b4-b61c-1301b079b0b8@tls.msk.ru/T/#t
+Forwarded: not-needed
+
+A use-after-free bug was reported when booting a Linux kernel during the
+pci setup phase. It's quite hard to reproduce (needs smp, and favored by
+having several pci devices with BAR and specific Linux config, which
+is Debian default one in this case).
+
+After investigation (see the associated bug ticket), it appears that,
+under specific conditions, we might access a cached AddressSpaceDispatch
+that was reclaimed by RCU thread meanwhile.
+In the Linux boot scenario, during the pci phase, memory region are
+destroyed/recreated, resulting in exposition of the bug.
+
+The core of the issue is that we cache the dispatch associated to
+current cpu in cpu->cpu_ases[asidx].memory_dispatch. It is updated with
+tcg_commit, which runs asynchronously on a given cpu.
+At some point, we leave the rcu critial section, and the RCU thread
+starts reclaiming it, but tcg_commit is not yet invoked, resulting in
+the use-after-free.
+
+It's not the first problem around this area, and this patch [1] already
+tried to address it. It did a good job, but it seems that we found a
+specific situation where it's not enough.
+
+This patch takes a simple approach: remove the cached value creating the
+issue, and make sure we always get the current mapping for address
+space, using address_space_to_dispatch(cpu->cpu_ases[asidx].as).
+It's equivalent to qatomic_rcu_read(&as->current_map)->dispatch;
+This is not really costly, we just need two dereferences,
+including one atomic (rcu) read, which is negligible considering we are
+already on mmu slow path anyway.
+
+Note that tcg_commit is still needed, as it's taking care of flushing
+TLB, removing previously mapped entries.
+
+Another solution would be to cache directly values under the dispatch
+(dispatch themselves are not ref counted), keep an active reference on
+associated memory section, and release it when appropriate (tricky).
+Given the time already spent debugging this area now and previously, I
+strongly prefer eliminating the root of the issue, instead of adding
+more complexity for a hypothetical performance gain. RCU is precisely
+used to ensure good performance when reading data, so caching is not as
+beneficial as it might seem IMHO.
+
+[1] https://gitlab.com/qemu-project/qemu/-/commit/0d58c660689f6da1e3feff8a997014003d928b3b
+
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3040
+Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
+Tested-by: Michael Tokarev <mjt@tls.msk.ru>
+---
+ system/physmem.c | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/system/physmem.c b/system/physmem.c
+index 130c148ffb5..e5dd760e0bc 100644
+--- a/system/physmem.c
++++ b/system/physmem.c
+@@ -165,13 +165,11 @@ static bool ram_is_cpr_compatible(RAMBlock *rb);
+ * CPUAddressSpace: all the information a CPU needs about an AddressSpace
+ * @cpu: the CPU whose AddressSpace this is
+ * @as: the AddressSpace itself
+- * @memory_dispatch: its dispatch pointer (cached, RCU protected)
+ * @tcg_as_listener: listener for tracking changes to the AddressSpace
+ */
+ typedef struct CPUAddressSpace {
+ CPUState *cpu;
+ AddressSpace *as;
+- struct AddressSpaceDispatch *memory_dispatch;
+ MemoryListener tcg_as_listener;
+ } CPUAddressSpace;
+
+@@ -692,7 +690,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr,
+ IOMMUTLBEntry iotlb;
+ int iommu_idx;
+ hwaddr addr = orig_addr;
+- AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch;
++ AddressSpaceDispatch *d = address_space_to_dispatch(cpu->cpu_ases[asidx].as);
+
+ for (;;) {
+ section = address_space_translate_internal(d, addr, &addr, plen, false);
+@@ -753,7 +751,7 @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu,
+ {
+ int asidx = cpu_asidx_from_attrs(cpu, attrs);
+ CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
+- AddressSpaceDispatch *d = cpuas->memory_dispatch;
++ AddressSpaceDispatch *d = address_space_to_dispatch(cpuas->as);
+ int section_index = index & ~TARGET_PAGE_MASK;
+ MemoryRegionSection *ret;
+
+@@ -2780,9 +2778,6 @@ static void tcg_log_global_after_sync(MemoryListener *listener)
+
+ static void tcg_commit_cpu(CPUState *cpu, run_on_cpu_data data)
+ {
+- CPUAddressSpace *cpuas = data.host_ptr;
+-
+- cpuas->memory_dispatch = address_space_to_dispatch(cpuas->as);
+ tlb_flush(cpu);
+ }
+
+@@ -2798,11 +2793,7 @@ static void tcg_commit(MemoryListener *listener)
+ cpu = cpuas->cpu;
+
+ /*
+- * Defer changes to as->memory_dispatch until the cpu is quiescent.
+- * Otherwise we race between (1) other cpu threads and (2) ongoing
+- * i/o for the current cpu thread, with data cached by mmu_lookup().
+- *
+- * In addition, queueing the work function will kick the cpu back to
++ * Queueing the work function will kick the cpu back to
+ * the main loop, which will end the RCU critical section and reclaim
+ * the memory data structures.
+ *
+--
+2.47.2
+
+
diff -Nru qemu-10.0.2+ds/debian/rules qemu-10.0.2+ds/debian/rules
--- qemu-10.0.2+ds/debian/rules 2025-05-12 09:53:18.000000000 +0300
+++ qemu-10.0.2+ds/debian/rules 2025-07-10 09:48:56.000000000 +0300
@@ -135,13 +135,8 @@
| tr _ - >> debian/$1.substvars
echo 'qemu:Conflicts=$(if $(filter $3,${system-kvm}),qemu-kvm)' >> debian/$1.substvars
${# construct list `arch1 arch2 (alias) arch3..' for Description and word-wrap it}
-list='$(foreach q,$2,$q$(if ${system-alias-$q}, (${system-alias-$q})))'; \
- len2=$$(($${#list}/2)); \
- if [ $$len2 -gt 36 ]; then \
- while expr substr "$$list" $$len2 1 != " " >/dev/null; do len2=$$(($$len2+1)); done; \
- list="$$(expr substr "$$list" 1 $$(($$len2-1)))\$${Newline} $$(expr substr "$$list" $$(($$len2+1)) $$len2)"; \
- fi; \
- echo "qemu:archlist=$$list" >> debian/$1.substvars
+echo 'qemu:archlist=$(foreach q,$2,$q$(if ${system-alias-$q}, (${system-alias-$q})))' \
+ | sed -E 's/(.{37,45})\s([^(].{9})/\1\$${Newline} \2/' >> debian/$1.substvars
dh_installdocs -p $1 --link-doc=qemu-system-common
${# keep empty line at the end }
endef
--- End Message ---