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;
     }