Commit 6682ea3391 for qemu.org
commit 6682ea3391277e732a6d74c5758206ba834e1615
Author: Stefan Hajnoczi <stefanha@redhat.com>
Date: Tue Jul 21 09:44:24 2026 -0400
virtio: avoid packed vring virtio_queue_empty() infinite loops (CVE-2026-16457)
Virtqueue handler functions in device emulation code often look
something like this:
while (!virtio_queue_empty(vq)) {
...pop and process virtqueue element...
}
virtio-blk, virtio-scsi, virtio-crypto, and vhost-shadow-virtqueue use
this pattern.
The device may break (i.e. hit an error that requires device reset)
during the loop. virtio_queue_empty() returns 1 for broken split vrings
but not for broken packed vrings, leading to an infinite loop.
Adjust the packed vring behavior to match split vrings and avoid
infinite loops.
Fixes: CVE-2026-16457
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3968
Reported-by: Anatol Belski <anbelski@linux.microsoft.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260721134424.196337-1-stefanha@redhat.com>
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 979c4065b7..daa5607338 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -763,6 +763,10 @@ static int virtio_queue_packed_empty_rcu(VirtQueue *vq)
struct VRingPackedDesc desc;
VRingMemoryRegionCaches *cache;
+ if (virtio_device_disabled(vq->vdev)) {
+ return 1;
+ }
+
if (unlikely(!vq->vring.desc)) {
return 1;
}