virtio_add_queue() allocates used_elems for num_default entries, but
virtio_queue_set_num() accepts larger guest-supplied queue sizes up to
VIRTQUEUE_MAX_SIZE. With VIRTIO_F_IN_ORDER, this lets the guest drive
used_elems accesses past the allocation and cause out-of-bounds reads
and writes.

Reject queue sizes larger than num_default in virtio_queue_set_num()
and mark the device broken.

Fixes: e63c0ba1bc ("virtio: Add support for guest setting of queue size")
Fixes: CVE-2026-50626
Cc: Peter Maydell <[email protected]>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3882
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3921
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3923
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3613
Signed-off-by: Michael S. Tsirkin <[email protected]>
---
 hw/virtio/virtio.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 340bac2607..ee9247f98f 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2440,6 +2440,11 @@ void virtio_queue_set_num(VirtIODevice *vdev, int n, int 
num)
         num < 0) {
         return;
     }
+    if (num > vdev->vq[n].vring.num_default) {
+        virtio_error(vdev, "virtio: queue %d size %d exceeds max size %u",
+                     n, num, vdev->vq[n].vring.num_default);
+        return;
+    }
     vdev->vq[n].vring.num = num;
 }
 
-- 
MST


Reply via email to