diff options
| author | Stefano Garzarella <sgarzare@redhat.com> | 2026-04-17 15:26:44 +0200 |
|---|---|---|
| committer | Michael Tokarev <mjt@tls.msk.ru> | 2026-06-16 19:15:20 +0300 |
| commit | b55b909db6244431799a0577ecfca9ff13e8397e (patch) | |
| tree | 2e838c02052df8011d932bc9446fda5b202a74f5 | |
| parent | 6d4d9b69de5789e1cd1500d6545ecdf8dccaf786 (diff) | |
| download | qemu-b55b909db6244431799a0577ecfca9ff13e8397e.tar.gz qemu-b55b909db6244431799a0577ecfca9ff13e8397e.zip | |
libvhost-user: fix buffer overflow in virtqueue_read_indirect_desc()
virtqueue_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,
vu_gpa_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: 293084a719 ("libvhost-user: Support across-memory-boundary access")
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-2-sgarzare@redhat.com>
(cherry picked from commit 85805ee887be4adddb1f1a34f526968adc95e582)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
| -rw-r--r-- | subprojects/libvhost-user/libvhost-user.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c index 9c630c2170..014d210748 100644 --- a/subprojects/libvhost-user/libvhost-user.c +++ b/subprojects/libvhost-user/libvhost-user.c @@ -2391,8 +2391,9 @@ static int virtqueue_read_indirect_desc(VuDev *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; @@ -2409,10 +2410,10 @@ virtqueue_read_indirect_desc(VuDev *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; |
