[PATCH] vhost: fix off-by-one in vhost_svq_next_desc with IN_ORDER

lirongqing posted 1 patch 2 weeks, 1 day ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260911081635.1872-1-lirongqing@baidu.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, "Eugenio Pérez" <eperezma@redhat.com>
hw/virtio/vhost-shadow-virtqueue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] vhost: fix off-by-one in vhost_svq_next_desc with IN_ORDER
Posted by lirongqing 2 weeks, 1 day ago
From: Li RongQing <lirongqing@baidu.com>

vhost_svq_next_desc checks id against vring.num before incrementing,
so when id == vring.num - 1 the function returns vring.num instead of
0.  This causes vhost_svq_vring_write_descs to write descs[num-1].next
= num (an invalid descriptor index) and, on the next iteration, to
access descs[num] — which lies past the descriptor ring and into the
avail ring, corrupting it.

The bug triggers whenever an IN_ORDER descriptor chain wraps around the
end of the SVQ ring.

Fix by incrementing id first, then checking for wrap-around.

Fixes: 485c9e69ef6e ("vhost: add in_order feature to shadow virtqueue")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
 hw/virtio/vhost-shadow-virtqueue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 9404762..d4f5299 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -155,7 +155,7 @@ static uint16_t vhost_svq_next_desc(const VhostShadowVirtqueue *svq,
                                     uint16_t id)
 {
     if (virtio_vdev_has_feature(svq->vdev, VIRTIO_F_IN_ORDER)) {
-        return (id == svq->vring.num) ? 0 : ++id;
+        return (++id == svq->vring.num) ? 0 : id;
     } else {
         return svq->desc_state[id].next;
     }
-- 
2.9.4