libvduse: fix buffer overflow in vduse_queue_read_indirect_desc()
vduse_queue_read_indirect_desc() copies an indirect descriptor table
into a buffer in chunks when the table crosses a memory region
boundary. The destination is a struct vring_desc pointer but is
advanced by a byte count, so each increment moves the pointer by
read_len elements instead of read_len bytes, writing beyond the
buffer.
Use a char pointer for the destination so that the arithmetic
advances correctly.
While at it, change the source from a struct vring_desc pointer
to a void pointer: when the table is split across regions,
iova_to_va() can return a pointer into the middle of a descriptor,
so casting it to a struct vring_desc pointer is wrong. The pointer is
only used as a memcpy() source, so a void pointer is fine.
Fixes: CVE-2026-6425
Fixes: a6caeee811 ("libvduse: Add VDUSE (vDPA Device in Userspace) library")
Cc: qemu-stable@nongnu.org
Reported-by: DARKNAVY <vr@darknavy.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260417132645.121192-3-sgarzare@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
85805ee887
commit
9f1b6d013d
@@ -465,8 +465,9 @@ static int
|
||||
vduse_queue_read_indirect_desc(VduseDev *dev, struct vring_desc *desc,
|
||||
uint64_t addr, size_t len)
|
||||
{
|
||||
struct vring_desc *ori_desc;
|
||||
char *dst_desc = (char *)desc;
|
||||
uint64_t read_len;
|
||||
void *ori_desc;
|
||||
|
||||
if (len > (VIRTQUEUE_MAX_SIZE * sizeof(struct vring_desc))) {
|
||||
return -1;
|
||||
@@ -483,10 +484,10 @@ vduse_queue_read_indirect_desc(VduseDev *dev, struct vring_desc *desc,
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(desc, ori_desc, read_len);
|
||||
memcpy(dst_desc, ori_desc, read_len);
|
||||
len -= read_len;
|
||||
addr += read_len;
|
||||
desc += read_len;
|
||||
dst_desc += read_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user