Commit 6dbdc271f5 for qemu.org

commit 6dbdc271f56b42e921a662b65a862f503eb4448e
Author: Laurent Vivier <lvivier@redhat.com>
Date:   Wed Jul 15 13:50:40 2026 +0200

    hw/virtio: reject zero-length packed indirect descriptor table

    The split-ring path already rejects a zero-length indirect descriptor
    table since commit 7423192912af ("virtio: add checks for the size of
    the indirect table"). The packed-ring path is missing the same check,
    allowing a guest to trigger an assertion in address_space_cache_init()
    with a packed indirect descriptor that has len=0.

    Add the same !desc.len check to the packed-ring indirect validation
    in both virtqueue_packed_get_avail_bytes() and virtqueue_packed_pop().

    Fixes: 86044b24e865 ("virtio: basic packed virtqueue support")
    Cc: jasowangio@gmail.com
    Cc: qemu-stable@nongnu.org
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3984
    Reported-by: dong ling <dongling226655@outlook.com>
    Signed-off-by: Laurent Vivier <lvivier@redhat.com>
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Message-ID: <20260715115040.2186274-1-lvivier@redhat.com>

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 7c19080db5..2d33622daf 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1475,7 +1475,7 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq,
         }

         if (desc.flags & VRING_DESC_F_INDIRECT) {
-            if (desc.len % sizeof(VRingPackedDesc)) {
+            if (!desc.len || (desc.len % sizeof(VRingPackedDesc))) {
                 virtio_error(vdev, "Invalid size for indirect buffer table");
                 goto err;
             }
@@ -1927,7 +1927,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
     vring_packed_desc_read(vdev, &desc, desc_cache, i, true);
     id = desc.id;
     if (desc.flags & VRING_DESC_F_INDIRECT) {
-        if (desc.len % sizeof(VRingPackedDesc)) {
+        if (!desc.len || (desc.len % sizeof(VRingPackedDesc))) {
             virtio_error(vdev, "Invalid size for indirect buffer table");
             goto done;
         }