* [PATCH v2 0/2] virtio_ring: reject a split ring size that is not a power of two again
@ 2026-11-12 15:49 Stjepan Poljak
2026-11-12 15:49 ` [PATCH v2 1/2] " Stjepan Poljak
2026-11-12 15:49 ` [PATCH v2 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak
0 siblings, 2 replies; 4+ messages in thread
From: Stjepan Poljak @ 2026-11-12 15:49 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang
Cc: Francesco Valla, 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.
Changes in v2:
- Patch 1: log with dev_err() rather than dev_warn(), and say in the
message why the length is bad (Francesco)
- Patch 2: commit message updated for the new message text
v1: https://lore.kernel.org/r/20261111172947.3579982-1-stjepan.poljak@gmail.com
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 | 7 +++++++
tools/virtio/vringh_test.c | 11 +++++++++++
2 files changed, 18 insertions(+)
base-commit: 1a577f9402c1780cc1e663f48d5dd54c02051b09
--
2.53.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v2 1/2] virtio_ring: reject a split ring size that is not a power of two again 2026-11-12 15:49 [PATCH v2 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak @ 2026-11-12 15:49 ` Stjepan Poljak 2026-11-14 7:57 ` Francesco Valla 2026-11-12 15:49 ` [PATCH v2 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two Stjepan Poljak 1 sibling, 1 reply; 4+ messages in thread From: Stjepan Poljak @ 2026-11-12 15:49 UTC (permalink / raw) To: Michael S. Tsirkin, Jason Wang Cc: Francesco Valla, 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" error 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 v2: - Log with dev_err() rather than dev_warn(), and say in the message why the length is bad (Francesco) --- drivers/virtio/virtio_ring.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index f683a2d6a200..f855b8d41575 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -3513,6 +3513,13 @@ 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_err(&vdev->dev, + "Bad virtqueue length %u (not a power of two)\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, -- 2.53.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2] virtio_ring: reject a split ring size that is not a power of two again 2026-11-12 15:49 ` [PATCH v2 1/2] " Stjepan Poljak @ 2026-11-14 7:57 ` Francesco Valla 0 siblings, 0 replies; 4+ messages in thread From: Francesco Valla @ 2026-11-14 7:57 UTC (permalink / raw) To: Stjepan Poljak Cc: Michael S. Tsirkin, Jason Wang, Eugenio Pérez, Xuan Zhuo, Andy Lutomirski, Bjorn Andersson, Mathieu Poirier, virtualization, linux-remoteproc, linux-kernel On Thu, Nov 12, 2026 at 04:49:16PM +0100, Stjepan Poljak wrote: > 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" error 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 > > v2: > - Log with dev_err() rather than dev_warn(), and say in the message why > the length is bad (Francesco) > --- > drivers/virtio/virtio_ring.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > index f683a2d6a200..f855b8d41575 100644 > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -3513,6 +3513,13 @@ 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_err(&vdev->dev, > + "Bad virtqueue length %u (not a power of two)\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, > -- > 2.53.0 > Reviewed-by: Francesco Valla <francesco@valla.it> Tested-by: Francesco Valla <francesco@valla.it> # AM67A, rpmsg with R5F ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] tools/virtio: vringh_test: check that a split ring must be a power of two 2026-11-12 15:49 [PATCH v2 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak 2026-11-12 15:49 ` [PATCH v2 1/2] " Stjepan Poljak @ 2026-11-12 15:49 ` Stjepan Poljak 1 sibling, 0 replies; 4+ messages in thread From: Stjepan Poljak @ 2026-11-12 15:49 UTC (permalink / raw) To: Michael S. Tsirkin, Jason Wang Cc: Francesco Valla, 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 (not a power of two) 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] 4+ messages in thread
end of thread, other threads:[~2026-11-14 7:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-11-12 15:49 [PATCH v2 0/2] virtio_ring: reject a split ring size that is not a power of two again Stjepan Poljak 2026-11-12 15:49 ` [PATCH v2 1/2] " Stjepan Poljak 2026-11-14 7:57 ` Francesco Valla 2026-11-12 15:49 ` [PATCH v2 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®