Linux virtualization list
 help / color / mirror / Atom feed
* [PATCH] vhost: fix used ring index wrap in vhost_add_used_n_in_order
@ 2026-10-20 23:29 Fang Xieyan
  2026-10-21  7:29 ` Eugenio Perez Martin
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Fang Xieyan @ 2026-10-20 23:29 UTC (permalink / raw)
  To: Michael S . Tsirkin, Jason Wang, Eugenio Pérez
  Cc: virtualization, kvm, netdev, stable, linux-kernel, Weibin Liu

vhost_add_used_n_in_order() advances start by nheads[i] but wraps it
with a single subtraction.  If start + nheads[i] >= 2 * vq->num, start
can remain outside the ring.

With used-ring logging enabled, start > vq->num makes (vq->num - start)
underflow.  log_write() then sets bits beyond the dirty-log bitmap,
potentially corrupting adjacent userspace memory.  This is reachable on
the vhost-net TX path with VIRTIO_F_IN_ORDER: done_idx can reach
VHOST_NET_BATCH (64), triggering the issue with a 32-entry ring.

Wrap start with a mask to keep it within the ring.  VHOST_SET_VRING_NUM
enforces a nonzero power-of-two ring size, allowing start to be wrapped
using & (vq->num - 1).

Fixes: 67a873df0c41 ("vhost: basic in order support")
Cc: stable@vger.kernel.org
Reviewed-by: Weibin Liu <liuwb@xiaopeng.com>
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
---
Reproducer (verified on a kernel containing commit 67a873df0c41 with a
temporary WARN_ON_ONCE probe in log_used(); the probe is not part of
this patch):

With VIRTIO_F_IN_ORDER, num=32, and used-ring dirty logging enabled, the
TX batch reaches done_idx=64.  In the observed run, the initial index is
3, so the single subtraction leaves start=35.  The resulting length
calculation wraps to 34359738344 bytes, as confirmed by the log_used()
probe.

A 64-byte canary immediately after the 512-byte log bitmap changes from
0xA5 to 0xFF, confirming the out-of-bounds write.  The used-ring canary
remains intact because vhost_put_used() runs before start is advanced;
the demonstrated corruption is in the dirty-log bitmap.

 drivers/vhost/vhost.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 44cac11b68d2..0226c4c59709 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -3172,8 +3172,7 @@ static int vhost_add_used_n_in_order(struct vhost_virtqueue *vq,
 		}
 		start += nheads[i];
 		new += nheads[i];
-		if (start >= vq->num)
-			start -= vq->num;
+		start &= vq->num - 1;
 	}
 
 	if (unlikely(vq->log_used)) {
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-22 10:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 23:29 [PATCH] vhost: fix used ring index wrap in vhost_add_used_n_in_order Fang Xieyan
2026-10-21  7:29 ` Eugenio Perez Martin
2026-10-21 23:30 ` sashiko-bot
2026-10-22 10:06 ` Fang Xieyan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox