diff options
author | Eric Auger <eric.auger@redhat.com> | 2023-07-17 18:21:26 +0200 |
---|---|---|
committer | Michael Tokarev <mjt@tls.msk.ru> | 2023-08-04 19:14:46 +0300 |
commit | 18963f458f71da2535e1c367ea66165d0cd9fd33 (patch) | |
tree | 381c5ef9297d08879d18c6980d16b49fe0a4b125 | |
parent | 71e05c42cc36d9d678db88583d9ece8be7b2f15c (diff) | |
download | qemu-18963f458f71da2535e1c367ea66165d0cd9fd33.zip qemu-18963f458f71da2535e1c367ea66165d0cd9fd33.tar.gz qemu-18963f458f71da2535e1c367ea66165d0cd9fd33.tar.bz2 |
hw/virtio-iommu: Fix potential OOB access in virtio_iommu_handle_command()
In the virtio_iommu_handle_command() when a PROBE request is handled,
output_size takes a value greater than the tail size and on a subsequent
iteration we can get a stack out-of-band access. Initialize the
output_size on each iteration.
The issue was found with ASAN. Credits to:
Yiming Tao(Zhejiang University)
Gaoning Pan(Zhejiang University)
Fixes: 1733eebb9e7 ("virtio-iommu: Implement RESV_MEM probe request")
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reported-by: Mauro Matteo Cascella <mcascell@redhat.com>
Cc: qemu-stable@nongnu.org
Message-Id: <20230717162126.11693-1-eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit cf2f89edf36a59183166ae8721a8d7ab5cd286bd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r-- | hw/virtio/virtio-iommu.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 1cd2581..e84300d 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -727,13 +727,15 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq) VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); struct virtio_iommu_req_head head; struct virtio_iommu_req_tail tail = {}; - size_t output_size = sizeof(tail), sz; VirtQueueElement *elem; unsigned int iov_cnt; struct iovec *iov; void *buf = NULL; + size_t sz; for (;;) { + size_t output_size = sizeof(tail); + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); if (!elem) { return; |