Commit Graph

121009 Commits

Author SHA1 Message Date
Michael Tokarev
e3ad0582fd Update version for 10.0.11 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
v10.0.11
2026-06-25 14:09:17 +03:00
Akshit Yadav
a34cc9750b linux-user: Fix AT_PHDR when program headers are relocated into their own segment
When a binary is patched or relocated such that the program header table is
moved into a separate PT_LOAD segment (rather than sitting at the start of the
first loadable segment), QEMU's AT_PHDR auxv entry becomes incorrect. The
loader was computing AT_PHDR as load_addr + e_phoff, which assumes the headers
are mapped 1:1 from file offset 0. This breaks when the headers are elsewhere.

The Linux kernel instead locates the PT_LOAD segment that contains e_phoff,
then computes the in-memory address as p_vaddr + (e_phoff - p_offset). This
correctly handles relocated headers.

Fix by:
1. Add phdr_addr field to image_info to cache the resolved address.
2. Initialize to load_addr + e_phoff (fallback for headers outside any PT_LOAD).
3. In the PT_LOAD mapping loop, detect if the segment contains e_phoff and
   override with the segment-relative address.
4. Use info->phdr_addr for AT_PHDR instead of the incorrect formula.

Signed-off-by: Akshit Yadav <valium7171@gmail.com>
Reviewed-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 156e536a7b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Aditya Gupta
d55463da56 hw/pci: Replace assert with bounds check and return
As reported in https://gitlab.com/qemu-project/qemu/-/work_items/3334,
callers of 'pci_host_config_{read,write}_common' can pass length as 8,
causing an assert failure

The original issue with pnv_phb3 triggering the assert was fixed in a
previous commit

Instead of asserting on invalid length, check if the length is valid
(<=4), otherwise return (with the failure error code in read)

Reported-by: Zexiang Zhang <chan9yan9@gmail.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260326190438.734239-3-adityag@linux.ibm.com>
(cherry picked from commit c7209c5671)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Aditya Gupta
d088b316c6 ppc/pnv_phb3: Error out on invalid config access
PHB in Power8 supports 8 byte registers, and hence the ops structure
allows accessing of 8 bytes in 'pnv_phb3_reg_ops'

Both 'pnv_phb3_reg_read' & 'pnv_phb3_reg_write' pass the arguments as is
to 'pnv_phb3_config_{read,write}', if offset is PHB_CONFIG_DATA.

This when called with size as 8, causes following assert failure in
'pci_host_config_read_common' & 'pci_host_config_write_common':

    assert(len <= 4);

Validate that size is <=4, before jumping to pci_host_config_{read,write}_common

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3334
Reported-by: Zexiang Zhang <chan9yan9@gmail.com>
Fixes: 9ae1329ee2 ("ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge")
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260326190438.734239-2-adityag@linux.ibm.com>
(cherry picked from commit 2181097812)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Matt Turner
aec8aff4ef linux-user/xtensa: fix unlock of uninitialized frame pointer on sigreturn
If lock_user_struct fails, frame is uninitialized but the badframe
label unconditionally calls unlock_user_struct on it. Handle the
lock failure inline so badframe is only reached with a valid lock.

Signed-off-by: Matt Turner <mattst88@gmail.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 54e08dbe8f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Matt Turner
07e6aa22bf linux-user/xtensa: save/restore FP registers across signal delivery
Add support for saving and restoring f0-f15 across signal delivery.
The target_xtensa_xtregs_fp struct carries 32-bit f-regs for cores
with XTENSA_OPTION_FP_COPROCESSOR; target_xtensa_xtregs_dfp carries
64-bit f-regs for cores with XTENSA_OPTION_DFP_COPROCESSOR.

Lock the xtregs region via lock_user before reading on sigreturn,
since sc_xtregs is a user-space pointer that may lie outside the
locked sigframe.

Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 6858e3a71c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Matt Turner
2c11498d44 target/xtensa: add cpu_set_fcr/fsr helpers to sync fp_status
Factor FCR→fp_status and FSR→fp_status synchronisation out of the
wur_fpu{2k,}_fcr/wur_fpu_fsr helpers into cpu_set_fcr(), cpu_set_fsr(),
and cpu_get_fsr(). Signal delivery code needs to restore the FP rounding
mode and exception flags without duplicating the flag-mapping tables.

cpu_set_fcr() applies the union mask 0xfffff07f (superset of the
wur_fpu_fcr mask 0x0000007f and the wur_fpu2k_fcr mask 0xfffff07f) so
that FCR bits valid only on fpu2k configs are preserved while MBZ bits
7-11 are always cleared.

Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 7e859bacea)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:36:05 +03:00
Ryan Zhang
c5333ef57b ui/sdl2: Set GL ES profile before creating initial GL context
When the user selects GLES via '-display sdl,gl=es', we need to set
SDL_GL_CONTEXT_PROFILE_MASK to SDL_GL_CONTEXT_PROFILE_ES before
calling SDL_GL_CreateContext(). This ensures SDL_GL_LoadLibrary()
loads the correct GLES driver instead of the desktop OpenGL driver.

Fix the below issue: qemu-system-aarch64: /usr/src/debug/libepoxy
/1.5.10/src/dispatch_common.c:872: epoxy_get_proc_address: Assertion
`0 && "Couldn't find current GLX or EGL context.\n"' failed.

sdl2_gl_create_context() already sets the profile mask correctly for
ES mode, but the initial context created in sdl2_window_create() is
missing the same treatment.

Fixes:da3f7a3ab9ea0091955b58f8909dfcee01f4043e ("ui/sdl: try to instantiate the matching opengl renderer")

Signed-off-by: ryan.zhang@nxp.com
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <DU2PR04MB9018BB3650BA218438C01F2A83042@DU2PR04MB9018.eurprd04.prod.outlook.com>
(cherry picked from commit 490a3e1867)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-24 16:35:40 +03:00
Christian Schoenebeck
90d713b15b hw/9pfs: reject . and .. in Twstat rename
The other Trename and Trenameat handlers already reject "." and ".."
as new name on rename requests by returning -EISDIR in this case.

The legacy Twstat rename handler is missing this validation. While passing
"." or ".." does not trigger a crash as fixed by the previous patch (since
the fs backend driver's system calls handle these gracefully), it creates
a behavioral inconsistency, as it is semantically meaningless to rename a
file to a directory reference in the first place.

Fix this by rejecting "." and ".." in Twstat rename handler with -EISDIR
to match behavior of Trename and Trenameat handlers.

Fixes: 8cf89e007a ("virtio-9p: Add P9_TWSTAT support")
Link: https://lore.kernel.org/qemu-devel/662333331d371c6c343c8091161de8eaa121880e.1780072238.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 08750e31fc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-19 08:47:15 +03:00
Christian Schoenebeck
02a1f7835e hw/9pfs: fix abort due to illegal name with Twstat rename
The legacy Twstat 9p request can be used to rename files and directories.
Unlike the other, more recent rename requests like Trename and Trenameat,
Twstat does not validate the submitted new name before passing it to
v9fs_complete_rename().

A priviliged guest user with direct communication access to 9p server
could pass a string containing '/' as new name, which causes an assertion
fault (DoS) in local_name_to_path().

Fix this by rejecting such strings by checking the client supplied new
name with name_is_illegal(), similar to how Trename and Trenameat handlers
do already.

Reported-by: Feifan Qian <bea1e@proton.me>
Fixes: 8cf89e007a ("virtio-9p: Add P9_TWSTAT support")
Link: https://lore.kernel.org/qemu-devel/ba09716828e82992f9d8cac7f00eee0bc1c43c61.1780072238.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 7f5445e7e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-19 08:47:15 +03:00
Mathias Krause
b7e3ea6eb3 gdbstub: Update x86 control register bits
The control register bits haven't been updated in a few years, making
them lack behind features QEMU ganied in these years.

Update them to the current version of the SDM and sort the 32bit version
to be in line with all the other definitions (descending order).

This should remove confusion when debugging, for example, CET-enabled
guests:

- before the change:
  (gdb) info registers cr4
  cr4            0x8000f0            [ PGE MCE PAE PSE ]

- after the change:
  (gdb) info registers cr4
  cr4            0x8000f0            [ CET PGE MCE PAE PSE ]

Signed-off-by: Mathias Krause <minipli@grsecurity.net>
Link: https://lore.kernel.org/r/20260327143413.254227-1-minipli@grsecurity.net
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 88d39a2937)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-19 08:43:08 +03:00
Paolo Bonzini
5f0e74c93d target/i386: apply mod to immediate count of an RCL/RCR operation
RCR and RCL instructions with a count of 9 are the same as if the
count was 0, but they generated incorrect code because the can_be_zero
flag is false.  This causes 0 to underflow into -1 at
tcg_gen_subi_tl(count, count, 1).

Fix by absorbing the modulo computation into gen_shift_count(), now
renamed gen_shift_count_1(), so that it can handle both reductions.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3452
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e38d0afade)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-19 08:37:21 +03:00
Gerd Hoffmann
6e7d0ddfc2 hw/uefi: fix parse_hexstr
Make sure we actually have two input characters available before going
to parse two hex digits.  Fixes one byte buffer overflow of the output
buffer in case the input string has an odd number of characters.

Fixes: CVE-2026-48915
Fixes: 12058948ab ("hw/uefi: add var-service-json.c + qapi for NV vars.")
Reported-by: Feifan Qian <bea1e@proton.me>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-ID: <20260526135948.599148-1-kraxel@redhat.com>
(cherry picked from commit d6601a7e1c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-18 00:29:44 +03:00
Abhigyan Kumar
e73255f1db target/riscv: mask vxrm csrw write to the low 2 bits
Citing the RISC-V specification:

    "The vector fixed-point rounding-mode register holds a two-bit
    read-write rounding-mode field in the least-significant bits
    (vxrm[1:0]). The upper bits, vxrm[XLEN-1:2], should be written as
    zeros."

QEMU wrote full value into env->vxrm causing read of upper bits too.
Used existing macros for bit-masking. Previous had a hard-coded value.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3470
Signed-off-by: Abhigyan Kumar <314abh@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Message-ID: <20260530102100.78150-1-314abh@gmail.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 9f550a0b63)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
21ca98189e disas/riscv.c: fix inst_length()
inst_length() can return 0 if 'inst' happens to not match any known
encoding (like [1]).  Returning 0 is not desirable, even for unknown
encodings, given that it will cause a loop in target_disas() later on.

The most recent version of the RISC-V unpriv spec ditched the
sophisticated instruction-length encoding.  We're now supporting only
16-bit and 32-bit length instructions, where:

"All the 32-bit instructions in the base ISA have their lowest two bits
set to 11.  The optional compressed 16-bit instruction-set extensions
have their lowest two bits equal to 00, 01, or 10."

So the code is now simpler, never returning 0, and in fact it's the same
thing we're already doing in insn_len() from target/riscv/internals.h.
Due to include shenarigans we can't use that function in disas/riscv.c,
but I believe we can cut ourselves some slack this time and not lose
sleep over a 1 line of duplicated logic.  We're documenting it though!

[1] https://gitlab.com/qemu-project/qemu/-/work_items/3479

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3479
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260527200355.2068879-2-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 758dce9c98)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
6464782893 target/riscv/cpu_helper.c: add PMA access fault
We're not doing anything special w.r.t PMA (Physical Memory Access)
related faults, handling them like regular faults that will eventually
turn to be regular page faults.

Turns out we can't do that.  Priv spec section "Virtual Address
Translation Process" mentions:

"If a store to the PTE at address a+va.vpn[i]×PTESIZE would violate a
PMA or PMP check, raise an access-fault exception corresponding to the
original access type."

This means that we should handle PMA violations with access faults, like
we're already doing with PMP.  One clear code path where we should throw
a PMA failure, exposed by [1], is the error return from
address_space_ld* call.

There's a separated issue with the error code being returned by them (it
always return DECODE_ERROR even with 'rejected' reads) that we're going
to work around it by assuming that we did a good job with the PTE
address sanitization beforehand, and interpret that the error here is
related to PMA.  This is of course not ideal but fixing this QEMU API is
out of scope for this work.

All this said, we'll set the new pmp_pma_violation flag when we have
either a PMP or a PMA fault, and everything else shall fall into place.

[1] https://gitlab.com/qemu-project/qemu/-/work_items/3502

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3502
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260522172502.320529-1-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 8e090ecfa9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
4463191962 target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val
We need to fault during any access done while PTE bits 62-61 are both
set, according to the RISC-V priv spec.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3494
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260521130727.2311629-1-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 3e33da68f1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
9ad7b15c49 target/riscv/insn_trans/trans_rvzicbo.c.inc: save opcode before helpers
All helpers from this file can trigger ILLEGAL_INSN exceptions via
check_zicbo_envcfg() directly, bypassing the usual exception code from
translate.c.   If we don't save the opcode before each helper,
riscv_raise_exception() is triggered and env->bins won't be unwind during
cpu_loop_exit_restore() (code path cpu_restore_state ->
cpu_restore_state_from_tb() -> restore_state_to_opc()).

And finally, in riscv_cpu_do_interrupt(), we will set (m)tval = 0 when we can,
instead, set it to the cbo opcode that generated the exception.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3380
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260520214704.1943652-1-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit d6c5855c76)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
09e8e27750 disas/riscv.c: add 'cbo' insns to disassembler
We forgot to add 'cbo' insns to disas/riscv.c.  The result is that the
disassembler recognizes all of them as 'lq', an insn that happens to
share the same opcode space.

While we're at it reorder cbo_* entries in insn32.decode using opcode
order instead of insn name.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3480
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260519204714.1376551-1-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 9273cda722)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
e7efb2fa07 target/riscv/csr.c: fix mstatus.UXL reserved value
By the priv spec the value "3" is marked as 'Reserved' for mstatus.UXL.
Handle a mstatus.UXL = 3 write by writing the current 'xl' instead.

Fixes: https://gitlab.com/qemu-project/qemu/-/work_items/3367
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260514194537.2416243-3-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit ddfd33f196)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
7c9787408a target/riscv/csr.c: do not allow mstatus MPV/GVA writes
The priv spec states the following about mstatus.MPV:

"The MPV bit (Machine Previous Virtualization Mode) is written by the
implementation whenever a trap is taken into M-mode."

And, about mstatus.GVA:

"Field GVA (Guest Virtual Address) is written by the implementation
whenever a trap is taken into M-mode."

Both are written during riscv_cpu_do_interrupt().  They're not supposed
to be written by userspace.  As far as write_mstatus goes these fields
are read only.  The same applies for mstatush.MPV/mstatush.GVA.

Fixes: 03dd405dd5 ("target/riscv: Support MSTATUS.MPV/GVA only when RVH is enabled")
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20260514194537.2416243-2-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 18645f1957)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-17 10:19:26 +03:00
Daniel Henrique Barboza
81073858e6 target/riscv/cpu_helper.c: allow LOAD_ADDR_MIS promotion to AMO fault
promote_load_fault() is missing the promotion of misaligned AMO load
addresses, i.e. RISCV_EXCP_LOAD_ADDR_MIS should be promoted to
RISCV_EXCP_STORE_AMO_ADDR_MIS when RISCV_UW2_ALWAYS_STORE_AMO (i.e.
always_storeamo is true).

All other load AMO faults are already being covered.

Cc: qemu-stable@nongnu.org
Fixes: 98f21c30f5 ("target/riscv: AMO operations always raise store/AMO fault")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3503
Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Message-ID: <20260522181353.429782-1-daniel.barboza@oss.qualcomm.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit d85a4ec06a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 22:38:15 +03:00
Eugenio Pérez
6e676a01bb virtio: Allow to fill a whole virtqueue in order
As the while steps < max_steps is already one less than the vq size, the
right maximum max_steps variable is queue length, not the maximum
possible remainder of % vq->vring.num.

Fixes: b44135daa3 ("virtio: virtqueue_ordered_fill - VIRTIO_F_IN_ORDER support")
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260304173535.2702587-2-eperezma@redhat.com>
(cherry picked from commit eceff0982f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 19:27:23 +03:00
Stefano Garzarella
5aee2ee368 libvduse: fix buffer overflow in vduse_queue_read_indirect_desc()
vduse_queue_read_indirect_desc() copies an indirect descriptor table
into a buffer in chunks when the table crosses a memory region
boundary. The destination is a struct vring_desc pointer but is
advanced by a byte count, so each increment moves the pointer by
read_len elements instead of read_len bytes, writing beyond the
buffer.

Use a char pointer for the destination so that the arithmetic
advances correctly.

While at it, change the source from a struct vring_desc pointer
to a void pointer: when the table is split across regions,
iova_to_va() can return a pointer into the middle of a descriptor,
so casting it to a struct vring_desc pointer is wrong. The pointer is
only used as a memcpy() source, so a void pointer is fine.

Fixes: CVE-2026-6425
Fixes: a6caeee811 ("libvduse: Add VDUSE (vDPA Device in Userspace) library")
Cc: qemu-stable@nongnu.org
Reported-by: DARKNAVY <vr@darknavy.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260417132645.121192-3-sgarzare@redhat.com>
(cherry picked from commit 9f1b6d013d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 19:15:43 +03:00
Stefano Garzarella
b55b909db6 libvhost-user: fix buffer overflow in virtqueue_read_indirect_desc()
virtqueue_read_indirect_desc() copies an indirect descriptor table
into a buffer in chunks when the table crosses a memory region
boundary. The destination is a struct vring_desc pointer but is
advanced by a byte count, so each increment moves the pointer by
read_len elements instead of read_len bytes, writing beyond the
buffer.

Use a char pointer for the destination so that the arithmetic
advances correctly.

While at it, change the source from a struct vring_desc pointer
to a void pointer: when the table is split across regions,
vu_gpa_to_va() can return a pointer into the middle of a descriptor,
so casting it to a struct vring_desc pointer is wrong. The pointer is
only used as a memcpy() source, so a void pointer is fine.

Fixes: CVE-2026-6425
Fixes: 293084a719 ("libvhost-user: Support across-memory-boundary access")
Cc: qemu-stable@nongnu.org
Reported-by: DARKNAVY <vr@darknavy.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260417132645.121192-2-sgarzare@redhat.com>
(cherry picked from commit 85805ee887)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 19:15:20 +03:00
Costas Argyris
6d4d9b69de tests/qtest: Add amd-iommu command buffer head wrap test
Add a qtest for AMD IOMMU command buffer head pointer wraparound.
The test programs a command buffer, fills it with COMPLETION_WAIT commands,
advances the tail to consume all but the final entry, then wraps the tail
to zero to force the final command to advance CmdHeadPtr past the end of
the buffer. The guest-visible CmdHeadPtr register must then wrap back to zero.

This covers the case fixed by an earlier CmdHeadPtr wraparound patch.

The Linux kernel AMD IOMMU driver is not affected by this bug because it
uses COMPLETION_WAIT with a memory store doorbell to detect command progress.

Signed-off-by: Costas Argyris <costas.argyris@amd.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260530183458.7778-1-costas.argyris@amd.com>
(cherry picked from commit 8a1c09cbd3)
(Mjt: context fixup in MAINTAINERS)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 17:47:15 +03:00
Alejandro Jimenez
aa6fc45019 amd_iommu: Update command buffer head ptr in MMIO region after wraparound
When processing a command, amdvi_cmdbuf_run() increments cmdbuf_head and
writes it to the emulated MMIO register space before checking whether it
has reached the end of the command buffer.

If the incremented value reaches the end of the buffer and the tail pointer
is zero, the loop exits and the COMMAND_HEAD offset still contains an
unwrapped value. There are no errors in command processing since internal
cmdbuf_head state is always correctly updated, but the spec defines the
CmdHeadPtr field in MMIO Offset 2000h Command Buffer Head Pointer Register
as RW i.e. guest-visible, so it should be kept consistent.

Wrap cmdbuf_head before updating COMMAND_HEAD so the MMIO-visible register
always matches the internal command buffer head pointer position.

Cc: qemu-stable@nongnu.org
Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Reviewed-by: Sairaj Kodilkar <sarunkod@amd.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260512150044.334867-1-alejandro.j.jimenez@oracle.com>
(cherry picked from commit 3c98e446af)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 17:45:41 +03:00
Paolo Bonzini
57a8fe8c3d amd_iommu: restrict command buffer head/tail ranges to ring size
The AMD IOMMU command buffer is a ring buffer of cmdbuf_len (a power
of two) entries.  Each entry is 16 bytes and the head pointer cycles
through the set:

  [0, 16, 32, ..., (cmdbuf_len - 1) * AMDVI_COMMAND_SIZE]

The tail pointer is written by the guest through the COMMAND_TAIL MMIO
register (offset 0x2008); the while loop in amdvi_cmdbuf_run() only
terminates when head == tail.  If tail is set to a value higher than
cmdbuf_len * 16, head will cycle through all the elements of the ring
buffer indefinitely, without ever matching tail.  Fix this by further
masking tail (and head, for consistency) against the size of the
ring buffer.

Reported-by: Yunhe Wang <yunhewwww@163.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260511113923.2478812-1-pbonzini@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 3097d54016)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-16 17:45:21 +03:00
Dominique Martinet
b5c8e7d291 linux-user: add preadv2/preadv2
Some programs apparently use these, like the python test suite.

The flags argument (rwf_t) is an int, with values shared on all arches
and does not need translating.

This was tested manually with the following python script:
```
import os
fd = os.open('test', os.O_RDWR|os.O_CREAT)
os.pwritev(fd, [b'test', b'ok'], 0, os.RWF_HIPRI)
buf = [bytearray(3), bytearray(10)]
os.preadv(fd, buf, 0, os.RWF_HIPRI)
print(buf[0])
print(buf[1])
```

Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit fb4c08147b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-14 08:53:07 +03:00
Thomas Huth
16df89d95f system/rtc: Fix a possible year-2038 integer overflow problem
rtc_realtime_clock_offset is initialized with:

  rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000;

And QEMU_CLOCK_REALTIME might be based on gettimeofday() in certain
cases (see get_clock_realtime() in include/qemu/timer.h). So this
counter will exceed 32 bits in the year 2038, thus we should not
store this value in a normal integer variable. Change it to a time_t
to fix the problem.
And while we're at it, also adjust the nearby rtc_host_datetime_offset
variable to be on the safe side in the related code.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit ae84c738e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-14 08:51:01 +03:00
Xinhui Yang
f5e02d6a30 linux-user/strace: add fsmount series of syscalls
Following the addition of fsmount(2) series of syscalls in the syscall
handler, strace support is added, with a dedicated function to print the
parameters of fsconfig(2), which contains parameters that can be
interpreted as multiple types.

Snippet of the strace dump when running `mount -t tmpfs tmpfs /media`:

18 fsopen(tmpfs,1) = 3
18 read(3,0x407fcf1c,8191) = -1 errno=61 (No data available)
18 fsconfig(3,FSCONFIG_SET_STRING,"source","tmpfs",0) = 0
18 read(3,0x407fce3c,8191) = -1 errno=61 (No data available)
18 fsconfig(3,FSCONFIG_CMD_CREATE,NULL,NULL,0) = 0
18 read(3,0x407fce3c,8191) = -1 errno=61 (No data available)
18 fsmount(3,1,0) = 4
18 read(3,0x407fce3c,8191) = -1 errno=61 (No data available)
18 statx(4,"",AT_EMPTY_PATH|AT_STATX_SYNC_AS_STAT,0x1000,0x407fee98) = 0
18 move_mount(4,,-100,/media,4) = 0
18 read(3,0x407fcfcc,8191) = -1 errno=61 (No data available)
18 close(3) = 0
18 close(4) = 0

v2: Fixed build on RHEL9 due to missing syscalls (Helge)

Signed-off-by: Xinhui Yang <cyan@cyano.uk>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 6e0aa9f6c7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-12 00:28:23 +03:00
Xinhui Yang
ec4c92057b linux-user: implement fsmount(2) series of syscalls
This series of syscalls replaces the old mount(2) syscall with a series
of syscalls that operates around a filesystem context. This series of
syscalls is available since Linux 5.2 and glibc 2.36+.

Their users include systemd since v259 and libmount from util-linux, and
possibly other widely used projects.

Preliminary checks are implemented to ensure the validity of the
interface.

v2: Add syscall wrappers in case the build machine does not
support the fsmount() syscalls. (added by Helge Deller)

Signed-off-by: Xinhui Yang <cyan@cyano.uk>
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Helge Deller <deller@gmx.de>
(cherry picked from commit 767c32fe69)
(Mjt: context fixup)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-12 00:28:15 +03:00
Richard Henderson
31710e350a fpu: Handle all rounding modes in partsN_uncanon_normal
Missed float_round_nearest_even_max when recomputing round.

CC: qemu-stable@nongnu.org
Fixes: 72330260cd ("softfloat: Add float_round_nearest_even_max")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Message-id: 20260608190155.637067-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a6a1f92d5a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 23:28:19 +03:00
Munkhbaatar Enkhbaatar
e5b0b727a5 hw/usb/hcd-ohci: Clean up USBPacket before freeing ISO TD packet
ohci_service_iso_td() allocates a USBPacket and frees it after synchronous
completion, but it does not call usb_packet_cleanup() first.

Call usb_packet_cleanup() before g_free() so resources owned by USBPacket
are released.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3463

Signed-off-by: Munkhbaatar Enkhbaatar <munkhuu0825@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 163f9a4e06)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 22:27:44 +03:00
Fabiano Rosas
4c0acec503 qed: Don't try to flush during incoming migration
It's not possible to access the image file while there is an incoming
migration in progress, the QEMU process doesn't hold any locks to the
storage at this point so nodes are inactive. Attempting to flush leads
to an assert at bdrv_co_write_req_prepare():

   assert(!(bs->open_flags & BDRV_O_INACTIVE))

The issue is reproducible by running iotest 181 on a host under cpu
load. The migration must coincide with the header already containing
the QED_F_NEED_CHECK flag.

The sequence of events is as follows, with the respective call stacks
referenced below:

During block device init, bdrv_qed_attach_aio_context() starts the
'need_check' timer. The timer will not fire during incoming migration
as it uses QEMU_CLOCK_VIRTUAL (to avoid this very issue, as the code
comment indicates).                                                   (0)

However, there's still bdrv_qed_drain_begin() which uses the fact that
the timer is live to decide whether to start the
qed_need_check_timer_entry() directly.                                (1)

The qed_need_check_timer_entry() eventually calls into
qed_write_header() -> bdrv_co_pwrite() leading to the assert.         (2)

Skip creating the 'need_check' timer whenever the image is inactive.

The stacks:

(0) == issues timer_mod ==
 #6  in qed_start_need_check_timer       at ../block/qed.c:340
 #7  in bdrv_qed_attach_aio_context      at ../block/qed.c:373
 #8  in bdrv_qed_do_open                 at ../block/qed.c:556
 #9  in bdrv_qed_open_entry              at ../block/qed.c:582
 #10 in coroutine_trampoline             at ../util/coroutine-ucontext.c:175
 #0  in qemu_coroutine_switch<+120>      at ../util/coroutine-ucontext.c:321
 #1  in qemu_aio_coroutine_enter<+356>   at ../util/qemu-coroutine.c:293
 #2  in aio_co_enter<+179>               at ../util/async.c:710
 #3  in aio_co_wake<+53>                 at ../util/async.c:695
 #4  in thread_pool_co_cb<+47>           at ../util/thread-pool.c:283
 #5  in thread_pool_completion_bh<+241>  at ../util/thread-pool.c:202
 #6  in aio_bh_call<+109>                at ../util/async.c:173
 #7  in aio_bh_poll<+299>                at ../util/async.c:220
 #8  in aio_poll<+690>                   at ../util/aio-posix.c:745
 #9  in bdrv_qed_open<+392>              at ../block/qed.c:607
 #10 in bdrv_open_driver<+327>           at ../block.c:1678
 #11 in bdrv_open_common<+1619>          at ../block.c:2008
 #12 in bdrv_open_inherit<+2556>         at ../block.c:4191
 #13 in bdrv_open<+118>                  at ../block.c:4286
 #14 in blk_new_open<+199>               at ../block/block-backend.c:458
 #15 in blockdev_init<+2011>             at ../blockdev.c:612
 #16 in drive_new<+3008>                 at ../blockdev.c:1008
 #17 in drive_init_func<+51>             at ../system/vl.c:662
 #18 in qemu_opts_foreach<+227>          at ../util/qemu-option.c:1148
 #19 in configure_blockdev<+350>         at ../system/vl.c:721
 #20 in qemu_create_early_backends<+343> at ../system/vl.c:2076
 #21 in qemu_init<+12483>                at ../system/vl.c:3778
 #22 in main<+46>                        at ../system/main.c:71

(1) == sees timer_pending ==
 #6  in bdrv_qed_drain_begin             at ../block/qed.c:391
 #7  in bdrv_do_drained_begin            at ../block/io.c:366
 #8  in bdrv_do_drained_begin_quiesce    at ../block/io.c:386
 #9  in bdrv_child_cb_drained_begin      at ../block.c:1207
 #10 in bdrv_parent_drained_begin_single at ../block/io.c:133
 #11 in bdrv_parent_drained_begin        at ../block/io.c:64
 #12 in bdrv_do_drained_begin            at ../block/io.c:364
 #13 in bdrv_drained_begin               at ../block/io.c:393
 #14 in blk_drain                        at ../block/block-backend.c:2101
 #15 in blk_unref                        at ../block/block-backend.c:544
 #16 in bdrv_open_inherit                at ../block.c:4197
 #17 in bdrv_open                        at ../block.c:4286
 #18 in blk_new_open                     at ../block/block-backend.c:458
 #19 in blockdev_init                    at ../blockdev.c:612
 #20 in drive_new                        at ../blockdev.c:1008
 #21 in drive_init_func                  at ../system/vl.c:662
 #22 in qemu_opts_foreach                at ../util/qemu-option.c:1148
 #23 in configure_blockdev               at ../system/vl.c:721
 #24 in qemu_create_early_backends       at ../system/vl.c:2076
 #25 in qemu_init                        at ../system/vl.c:3778
 #26 in main                             at ../system/main.c:71

(2) == crashes ==
 #5  in __assert_fail (assertion="!(bs->open_flags & BDRV_O_INACTIVE)", file="../block/io.c", line=1977
 #6  in bdrv_co_write_req_prepare  at ../block/io.c:1977
 #7  in bdrv_aligned_pwritev       at ../block/io.c:2099
 #8  in bdrv_co_pwritev_part       at ../block/io.c:2316
 #9  in bdrv_co_pwritev            at ../block/io.c:2233
 #10 in bdrv_co_pwrite             at ../include/block/block_int-io.h:77
 #11 in qed_write_header           at ../block/qed.c:128
 #12 in qed_need_check_timer       at ../block/qed.c:305
 #13 in qed_need_check_timer_entry at ../block/qed.c:319

Note that this issue is not exactly the same as what's been reported
in Gitlab, but given how easily this reproduces, I imagine it has to
be happening in that setup as well.

Link: https://gitlab.com/qemu-project/qemu/-/work_items/3515
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Message-ID: <20260603193813.2327596-1-farosas@suse.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7e573b660f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:58:40 +03:00
Thomas Lamprecht
ae4c0e5730 qcow2: Fix data loss on zero write with detect-zeroes=unmap
Commit b8bfb1478d ("qcow2: Fix corruption on discard during write with
COW") added a wait_for_dependencies() at the start of
qcow2_subcluster_zeroize(). That fixes the inconsistency it set out to
fix, but turns the lock-protected pre-check in the caller,
qcow2_co_pwrite_zeroes(), into a stale one: the wait yields s->lock,
so an in-flight allocating write whose QCowL2Meta is already on
s->cluster_allocs (but whose L2 entry is not yet linked) gets to link
its entry during the yield. When the zeroize wakes, the cluster is now
NORMAL, and with BDRV_REQ_MAY_UNMAP the free path in zero_in_l2_slice()
unmaps the just-written cluster, silently dropping the data write's
payload.

This is reachable with detect-zeroes=unmap (the default for VirtIO
disks with discard on in Proxmox VE), under which the block layer
auto-promotes all-zero buffers to BDRV_REQ_ZERO_WRITE |
BDRV_REQ_MAY_UNMAP. A memory-constrained Debian guest running 'apt
full-upgrade' on such a disk reproduces it as random SIGSEGVs:
swapped-out code pages come back as zero.

Wait for in-flight dependencies before the lock-protected check in
qcow2_co_pwrite_zeroes(). If a write linked its L2 entry during the
wait, the type check now fails and the block layer falls back to a
bounce-buffered zero write that only touches the requested subrange,
preserving the racing write's data. Promote wait_for_dependencies() to
qcow2_wait_for_dependencies() so qcow2.c can call it.

Fixes: b8bfb1478d ("qcow2: Fix corruption on discard during write with COW")
Fixes: 9c3d7bf39f ("qcow2: Fix corruption on discard during write with COW") in 10.0.x series
Cc: qemu-stable@nongnu.org
Tested-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Message-ID: <20260522151318.238064-1-t.lamprecht@proxmox.com>
[kwolf: Reverted unnecessary change to 'nr' assignment]
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 1d47eb6898)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:50:26 +03:00
Kevin Wolf
e60fa4a9f5 iotests/046: Test that discard/write_zeroes wait for dependencies
This is a regression test for the bug fixed in the previous commit where
discard and write_zeroes operations wouldn't consider their dependencies
in s->cluster_allocs. Without the fix, this results in a corrupted
image.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20260427170520.101242-5-kwolf@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Tested-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 389f5bcc74)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:48:34 +03:00
Kevin Wolf
9c3d7bf39f qcow2: Fix corruption on discard during write with COW
Most code in qcow2 that accesses (and potentially modifies) L2 tables
does so while holding s->lock.

There is one exception, which is allocating writes. They hold the lock
initially while allocating clusters, but drop it for writing the guest
payload before taking the lock again for updating the L2 tables. This
allows concurrent requests that touch other parts of the image file to
continue in parallel and is an important performance optimisation.

However, this means that other requests that run while the lock is
dropped for writing guest data must synchronise with the list of
allocating requests in s->cluster_allocs and wait if they would overlap.
For writes, this is done in handle_dependencies(), but discard and write
zeros operations neglect to synchronise with s->cluster_allocs.

This means that discard can free a cluster whose L2 entry will already
be modified in qcow2_alloc_cluster_link_l2() by a previously started
write. In the case of a pre-allocated zero cluster that is in the
process of being overwritten, this means that discard can lead to a
situation where the cluster is still mapped (because the write will
restore the L2 entry just without the zero flag), but its refcount has
been decreased, resulting in a corrupted image.

Add the missing synchronisation to qcow2_cluster_discard() and
qcow2_subcluster_zeroize() to fix the problem.

Cc: qemu-stable@nongnu.org
Reported-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20260427170520.101242-4-kwolf@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Tested-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b8bfb1478d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:48:34 +03:00
Kevin Wolf
827192607b qemu-io: Add 'aio_discard' command
Testing interactions between multiple requests that include discard
requests require that qemu-io can do the discard asynchronously, like it
already does for reads and writes. To this effect, add an 'aio_discard'
command.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20260427170520.101242-3-kwolf@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Tested-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7f8466e2ce)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:48:34 +03:00
Stefan Hajnoczi
d2e7fd9fe2 virtio-blk: add missing VIRTIO_BLK_T_SCSI_CMD size check (CVE-2026-48914)
Check that the iovec containing struct virtio_scsi_inhdr is large enough
before storing an error value there.

Feifan Qian <bea1e@proton.me> pointed out that this can be used to
corrupt heap memory when the descriptor uses an MMIO address and a
length of 1, forcing QEMU to allocate a 1-byte heap bounce buffer.
virtio_stl_p() stores 4 bytes and therefore corrupts whatever is beyond
the bounce buffer.

Fixes: CVE-2026-48914
Fixes: f34e73cd69 ("virtio-blk: report non-zero status when failing SG_IO requests")
Reported-by: Feifan Qian <bea1e@proton.me>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20260526154957.1741622-1-stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit aeea0c2804)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-11 06:38:44 +03:00
Fiona Ebner
01abfc1ae1 block/io: fallback to bounce buffer if BLKZEROOUT is not supported because of alignment
Commit 5634622bcb ("file-posix: allow BLKZEROOUT with -t writeback")
enables the BLKZEROOUT ioctl when using 'writeback' cache, regressing
certain 'qemu-img convert' invocations, because of a pre-existing
issue. Namely, the BLKZEROOUT ioctl might fail with errno EINVAL when
the request is shorter than the block size of the block device.
Fallback to the bounce buffer, similar to when the ioctl is not
supported at all, rather than treating such an error as fatal.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3257
Resolves: https://bugzilla.proxmox.com/show_bug.cgi?id=7197
Cc: qemu-stable@nongnu.org
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20260105143416.737482-1-f.ebner@proxmox.com>
[Added TODO comment describing a larger fix that could be implemented in
the future.
--Stefan]
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit b4e28c304b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-08 20:27:51 +03:00
Farhan Ali
34cbeb27ff s390x/pci: Fix interrupt forwarding disable for interpreted devices
Remove the FH_MASK_ENABLE check when disabling interrupt forwarding
during device reset. This check was broken for the default case in
the switch statement above, preventing proper cleanup of interrupt
forwarding.

The pbdev->aif check in s390_pci_kvm_aif_disable() already guards
against double-disabling of interrupt forwarding.

Cc: qemu-stable@nongnu.org
Reported-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Omar Elghoul <oelghoul@linux.ibm.com>
Message-ID: <20260521182946.1607-1-alifm@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 442f727b8b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-07 07:25:43 +03:00
Alexandra Winter
e9f0c22c6a target/s390x: Make container ids in SysIB_15x 1-based
The Container Id in a container-type TLE of SysIB_15x is defined as 8-bit
unsigned nonzero integer. Make stsi fc 15 emulation architecture compliant,
by starting the container ids at 1 for the lowest numbered container.

The qemu misbehaviour without this patch becomes obvious due to a recently
proposed kernel fix. Older linux kernels pass the container ids from stsi
fc15 unchanged to sysfs, i.e. starting at 1 on s390 hardware. This resulted
in off-by-one values when compared to the values from HMC. A Linux kernel
fix is being proposed to correct the sysfs topology ids by -1, so they
start at 0, e.g. when displayed by 'lscpu -ye'. In case a KVM guest with a
fixed kernel runs on a host with a qemu without this fix, this can result
in container ids erroneously being shown as 255.
Example (Fixed guest on unfixed qemu):
$ lscpu -ye
CPU NODE DRAWER BOOK SOCKET CORE L1d:L1i:L2 ONLINE CONFIGURED POLARIZATION ADDRESS
  0    0    255  255    255    0 0:0:0         yes yes        vert-medium  0
  1    0    255  255      0    1 1:1:1         yes yes        vert-medium  1
After this fix:
$ lscpu -ye
CPU NODE DRAWER BOOK SOCKET CORE L1d:L1i:L2 ONLINE CONFIGURED POLARIZATION ADDRESS
  0    0      0    0      0    0 0:0:0         yes yes        vert-medium  0
  1    0      0    0      1    1 1:1:1         yes yes        vert-medium  1

Fixes: f4f54b582f ("target/s390x/cpu topology: handle STSI(15) and build the SYSIB")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Acked-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Gautam Gala <ggala@linux.ibm.com>
Message-ID: <20260511134909.43802-1-wintera@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 1f1ccb6f3c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-07 07:23:12 +03:00
Denis V. Lunev
3c03b50076 tests/unit: add test-envlist covering setenv/unsetenv name matching
util/envlist had no test coverage. Add tests/unit/test-envlist
exercising the public envlist API and pinning down the prefix-match
hazard fixed in the previous commit:

  - envlist_unsetenv("FOO") must not remove an entry named "FOOBAR";
  - envlist_setenv("FOO=...") must not replace an existing "FOOBAR=..."
    entry placed earlier in the list (envlist_setenv() inserts at the
    head, so the first prefix match wins under the old strncmp rule).

Also cover the rest of the contract: head-insertion order observed
through envlist_to_environ(), replacement of an existing variable,
the count argument of envlist_to_environ(), and the documented EINVAL
paths (NULL inputs, setenv without '=', unsetenv with '=').

Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20260520212628.479772-3-den@openvz.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 05221c600a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-04 22:57:10 +03:00
Denis V. Lunev
69a43064dc util/envlist: fix prefix-match in envlist_unsetenv() name lookup
envlist_unsetenv() looked up the entry to remove with
strncmp(entry->ev_var, env, strlen(env)). The comparison length is
the requested name's length, so any stored entry whose name *starts*
with that name compares equal. envlist_setenv() inserts at the head
of the list, so the first hit wins: with FOO=... stored first and
FOOBAR=... stored afterward, envlist_unsetenv("FOO") iterates from
the head, matches FOOBAR=... on the prefix, and drops it instead of
FOO=...

linux-user and bsd-user reach this code via the -U command-line
switch, so the bug is reachable from a normal qemu-user invocation.

envlist_setenv() used the same strncmp pattern but with
envname_len = (eq_sign - env + 1), so the '=' byte sat inside the
compared window and acted as an implicit boundary. setenv was
therefore not buggy -- but the safety lived in the byte layout of
ev_var rather than in the entry, so a future edit could easily
drift the two sites apart again.

Store the name length on each entry at insertion time and compare
with explicit length equality plus memcmp via a small helper. Use
the helper at both lookup sites so the boundary becomes a
structural property of the entry: envlist_unsetenv() stops
prefix-matching, and envlist_setenv()'s self-search no longer
depends on the '=' byte serving as a sentinel.

Fixes: 04a6dfebb6 ("linux-user: Add generic env variable handling")
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20260520212628.479772-2-den@openvz.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit c131ae56c1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-04 22:56:55 +03:00
sin99xx
e9cd45327e 9pfs: fix missing rename lock in v9fs_co_readdir_many (CVE-2026-48004)
v9fs_co_readdir_many() dispatches do_readdir_many() to a worker thread
that reads V9fsFidState's path.data without holding a rename lock.

A concurrent rename request, e.g. of its parent dir, causes the FID's
absolute path to be altered by freeing the old path string and
assigning a new one. This causes a heap-use-after-free race condition
while do_readdir_many() is still accessing the old object.

This allows a DoS by an unprivileged guest user.

Fix this by wrapping the worker thread dispatch block within a pair of
v9fs_path_read_lock() and v9fs_path_unlock() calls, like it's done at
other places.

Fixes: 2149675b19 ("9pfs: add new function v9fs_co_readdir_many()")
Fixes: CVE-2026-48004
Reported-by: sin99xx <sin99xx@proton.me>
Signed-off-by: sin99xx <sin99xx@proton.me>
[Christian Schoenebeck: add commit log message]
Link: https://lore.kernel.org/qemu-devel/E1wPkYi-000adH-4E@kylie.crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 5a8da7e979)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-01 21:02:55 +03:00
Christian Schoenebeck
7e35875428 tests/9pfs: add deep absolute path test
Add fs_deep_absolute_path test that creates a deep directory
structure with an absolute path length exceeding 16-bit range
(i.e. >65536) to verify the previous buffer overflow fix.

This is a slow test (may take several seconds) and therefore
registered as "slow" test and not running by default.

Use -m slow to run this test.

Link: https://gitlab.com/qemu-project/qemu/-/issues/3358
Link: https://lore.kernel.org/qemu-devel/933552b2cfc2c442fac7f4e68c777dce20ee8d7e.1779126034.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 198627807a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-01 21:02:55 +03:00
Christian Schoenebeck
c56c4b8d1c tests/qtest/libqos: add qvirtqueue_reset_pool() for descriptor pool reset
Add a function to reset the virtqueue descriptor pool state without
reinitializing the device. This is useful for tests that issue a high
number of requests and are limited by the simplified virtio test
driver's descriptor tracking, which decrements num_free but never
increments it back.

The function is safe for synchronous test code where requests are
sent and completed before the next request is issued.

Acked-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/qemu-devel/96cf23eea1204b34443218fe76bd4a5eaf9163e8.1779126034.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit be33c56898)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-01 21:02:55 +03:00
Christian Schoenebeck
a336841626 hw/9pfs: let callers of v9fs_path_sprintf() and v9fs_fix_path() handle errors
This patch mitigates issues with very large absolute paths.

- Add error handling to all v9fs_path_sprintf() calls in
  local_name_to_path()

- Update callers of v9fs_fix_path() to check return values.

- When path formatting fails, clunk the affected FIDs to prevent use of
  invalid paths.

- Use g_autofree for temporary variables to simplify code.

Even though paths are usually limited to PATH_MAX (typically 4k) on guest,
this limitation can be circumvented by using *at() functions on guest and
creating very deep directory structures. This was a problem for QEMU 9p
server, as it currently tracks the absolute path for each FID internally
that always requires assembly of a (potentially ver large) absolute path.

A true long-term fix would be getting rid of storing an absolute path for
each FID internally. However that would likely be a massive change with
uncertain implications.

This patch therefore just mitigates the problem by immediately clunking
(i.e. closing) all FIDs whose path exceed a limit that we could handle.
As this only accounts to very unusual large absolute paths not ever been
reported on (sane) production machines, this is currently considered an
acceptable mitigation that should only (counter)affect malicious attempts.

Fixes: 2f008a8c97 ("hw/9pfs: Use the correct signed type ...")
Reported-by: Wang Jihe <wangjihe.mail@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3358
Link: https://lore.kernel.org/qemu-devel/1d11dcbfc95b811dcdb48c6d7f3894d0ebd073a2.1779126034.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 3802c0e755)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-01 21:02:55 +03:00
Christian Schoenebeck
a71e1a8cd1 hw/9pfs: add error handling to v9fs_fix_path()
Update v9fs_fix_path() to return int and propagate errors from
v9fs_path_sprintf(). This allows callers to detect and handle
path formatting failures.

Link: https://lore.kernel.org/qemu-devel/a0592741a918b7cbe751980ec7ec0c03f505924c.1779126034.git.qemu_oss@crudebyte.com
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
(cherry picked from commit 54dd352c59)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2026-06-01 21:02:55 +03:00