@samitouri / QOSamiQemu / commits / 6682ea3391

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>

Stefan Hajnoczi committed Jul 21, 2026 at 09:44 UTC 6682ea3391277e732a6d74c5758206ba834e1615
1 file changed +4
hw/virtio/virtio.c
+4
@@ -763,6 +763,10 @@ static int virtio_queue_packed_empty_rcu(VirtQueue *vq)
763 struct VRingPackedDesc desc;
764 VRingMemoryRegionCaches *cache;
765
766 + if (virtio_device_disabled(vq->vdev)) {
767 + return 1;
768 + }
769 +
770 if (unlikely(!vq->vring.desc)) {
771 return 1;
772 }