From 4d412df37f25cd28fa21b9614eaf37ee69df3f53 Mon Sep 17 00:00:00 2001 From: Ben Levinsky Date: Mon, 14 Sep 2026 11:29:49 -0700 Subject: [PATCH] remoteproc: Validate virtqueue alignment The remote resource table controls the vring alignment, which is used for pointer rounding without validation. vring_init() rounds the used ring address with a ~(align - 1) mask, so a zero alignment leaves a NULL used ring that is dereferenced later. Reject a zero alignment before calculating the vring size and before storing the vring metadata taken from the resource table. Signed-off-by: Ben Levinsky Assisted-by: Codex:GPT-5 --- lib/include/openamp/remoteproc_virtio.h | 2 +- lib/remoteproc/remoteproc.c | 3 +++ lib/remoteproc/remoteproc_virtio.c | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/include/openamp/remoteproc_virtio.h b/lib/include/openamp/remoteproc_virtio.h index f56026a..dcf2066 100644 --- a/lib/include/openamp/remoteproc_virtio.h +++ b/lib/include/openamp/remoteproc_virtio.h @@ -94,7 +94,7 @@ void rproc_virtio_remove_vdev(struct virtio_device *vdev); * @param va vring virtual address * @param io Pointer to vring I/O region * @param num_descs Number of descriptors - * @param align vring alignment + * @param align vring alignment, must be nonzero * * @return 0 for success, negative value for failure. */ diff --git a/lib/remoteproc/remoteproc.c b/lib/remoteproc/remoteproc.c index da54e8e..3270ac0 100644 --- a/lib/remoteproc/remoteproc.c +++ b/lib/remoteproc/remoteproc.c @@ -1017,6 +1017,9 @@ remoteproc_create_virtio(struct remoteproc *rproc, da = vring_rsc->da; num_descs = vring_rsc->num; align = vring_rsc->align; + /* A zero alignment makes vring_init() compute a NULL used ring. */ + if (!align) + goto err1; size = vring_size(num_descs, align); va = remoteproc_mmap(rproc, NULL, &da, size, 0, &io); if (!va) diff --git a/lib/remoteproc/remoteproc_virtio.c b/lib/remoteproc/remoteproc_virtio.c index 4eb4076..c7630a8 100644 --- a/lib/remoteproc/remoteproc_virtio.c +++ b/lib/remoteproc/remoteproc_virtio.c @@ -361,8 +361,11 @@ int rproc_virtio_init_vring(struct virtio_device *vdev, unsigned int index, struct virtio_vring_info *vring_info; unsigned int num_vrings; + if (!vdev) + return -RPROC_EINVAL; num_vrings = vdev->vrings_num; - if ((index >= num_vrings) || (num_descs > RPROC_MAX_VRING_DESC)) + /* Recheck the resource values before storing the vring metadata. */ + if (index >= num_vrings || num_descs > RPROC_MAX_VRING_DESC || !align) return -RPROC_EINVAL; vring_info = &vdev->vrings_info[index]; vring_info->io = io;