* [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again
@ 2026-11-11 17:29 Stjepan Poljak
2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak
2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
0 siblings, 2 replies; 3+ messages in thread
From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson,
Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel
The split ring indexes its rings with num - 1 as a mask, so its size
must be a power of two. vring_new_virtqueue() lost that check in v4.6,
with commit 2a2d1382fe9d ("virtio: Add improved queue allocation API"),
and remoteproc passes it a ring size taken from firmware. A firmware
that asks for, e.g. 100 entries gets a ring on which the driver and
the device disagree on where the buffers are, so the device can read
the wrong ones. The only thing remoteproc checks is that ring size
and alignment are not zero. The other caller, mlxbf-tmfifo, uses a
hardcoded size of 1024, so it is not affected unless that value is
changed.
Patch 1 puts the check back; patch 2 adds a vringh_test case for it.
Tested in userspace with tools/virtio only, not on remoteproc hardware.
Stjepan Poljak (2):
virtio_ring: reject a split ring size that is not a power of two again
tools/virtio: vringh_test: check that a split ring must be a power of
two
drivers/virtio/virtio_ring.c | 6 ++++++
tools/virtio/vringh_test.c | 11 +++++++++++
2 files changed, 17 insertions(+)
base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] virtio_ring: reject a split ring size that is not a power of two again
2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak
@ 2026-11-11 17:29 ` Stjepan Poljak
2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
1 sibling, 0 replies; 3+ messages in thread
From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson,
Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel
The split ring indexes its avail and used rings with num - 1 as a mask,
so its size must be a power of two. Commit 2a2d1382fe9d ("virtio: Add
improved queue allocation API") moved that check from
vring_new_virtqueue() into the new allocation path, which
vring_new_virtqueue() does not use.
remoteproc calls vring_new_virtqueue() with a ring size from the
firmware, checked only to be non-zero. With 100 entries, for example,
the driver would put buffers 4 and 8 in avail slot 0. The device would
look for them at slots 4 and 8, possibly reading the wrong data.
Put the check back for the split ring; the packed ring has no such
restriction.
Fixes: 2a2d1382fe9d ("virtio: Add improved queue allocation API")
Signed-off-by: Stjepan Poljak <stjepan.poljak@gmail.com>
---
remoteproc still reports this as -ENOMEM, although the "Bad virtqueue
length" warning names the cause. Returning an error pointer from
vring_new_virtqueue() is left for later; the same change for
vring_create_virtqueue() is here:
https://lore.kernel.org/r/20261106055635.3019889-1-stjepan.poljak@gmail.com
---
drivers/virtio/virtio_ring.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index f683a2d6a200..8da9bd0e70f4 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -3513,6 +3513,12 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
name, map);
}
+ /* The split ring indexes its rings with num - 1 as a mask. */
+ if (!is_power_of_2(num)) {
+ dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+ return NULL;
+ }
+
vring_init(&vring_split.vring, num, pages, vring_align);
return __vring_new_virtqueue_split(index, &vring_split, vdev, weak_barriers,
context, notify, callback, name,
base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two
2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak
2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak
@ 2026-11-11 17:29 ` Stjepan Poljak
1 sibling, 0 replies; 3+ messages in thread
From: Stjepan Poljak @ 2026-11-11 17:29 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson,
Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel
vring_new_virtqueue() used to accept a split ring of any size, although
the ring is indexed with num - 1 as a mask. Check that it now refuses
one size short of RINGSIZE.
Without the preceding fix, vringh_test fails with:
vringh_test: vring_new_virtqueue accepted size 255
With it, vring_new_virtqueue() prints "Bad virtqueue length 255" and the
rest of the test runs as before.
Signed-off-by: Stjepan Poljak <stjepan.poljak@gmail.com>
---
tools/virtio/vringh_test.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c
index 2a5d7f7d2d6c..75c66385502d 100644
--- a/tools/virtio/vringh_test.c
+++ b/tools/virtio/vringh_test.c
@@ -494,6 +494,17 @@ int main(int argc, char *argv[])
__user_addr_max = __user_addr_min + USER_MEM;
memset(__user_addr_min, 0, vring_size(RINGSIZE, ALIGN));
+ /*
+ * The split ring indexes its rings with num - 1 as a mask, so a
+ * size that is not a power of two must be refused.
+ */
+ vq = vring_new_virtqueue(0, RINGSIZE - 1, ALIGN, &vdev, true, false,
+ __user_addr_min,
+ never_notify_host, never_callback_guest,
+ "guest vq");
+ if (vq)
+ errx(1, "vring_new_virtqueue accepted size %u", RINGSIZE - 1);
+
/* Set up guest side. */
vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, false,
__user_addr_min,
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-11 17:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 17:29 [PATCH 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak
2026-11-11 17:29 ` [PATCH 1/2] " Stjepan Poljak
2026-11-11 17:29 ` [PATCH 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®