virtio-iommu: add error check before assert
A fuzzer case discovered by Zheyu Ma causes an assert failure. Add a check before the assert, and respond with an error before moving on to the next queue element. To reproduce the failure: cat << EOF | \ qemu-system-x86_64 \ -display none -machine accel=qtest -m 512M -machine q35 -nodefaults \ -device virtio-iommu -qtest stdio outl 0xcf8 0x80000804 outw 0xcfc 0x06 outl 0xcf8 0x80000820 outl 0xcfc 0xe0004000 write 0x10000e 0x1 0x01 write 0xe0004020 0x4 0x00001000 write 0xe0004028 0x4 0x00101000 write 0xe000401c 0x1 0x01 write 0x106000 0x1 0x05 write 0x100001 0x1 0x60 write 0x100002 0x1 0x10 write 0x100009 0x1 0x04 write 0x10000c 0x1 0x01 write 0x100018 0x1 0x04 write 0x10001c 0x1 0x02 write 0x101003 0x1 0x01 write 0xe0007001 0x1 0x00 EOF Reported-by: Zheyu Ma <zheyuma97@gmail.com> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2359 Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> Message-Id: <20240613-fuzz-2359-fix-v2-manos.pitsidianakis@linaro.org> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
25b8a0f40c
commit
704391f94a
@ -974,6 +974,9 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
|
||||
iov = elem->out_sg;
|
||||
sz = iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head));
|
||||
if (unlikely(sz != sizeof(head))) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: read %zu bytes from command head"
|
||||
"but expected %zu\n", __func__, sz, sizeof(head));
|
||||
tail.status = VIRTIO_IOMMU_S_DEVERR;
|
||||
goto out;
|
||||
}
|
||||
@ -1010,6 +1013,25 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
|
||||
out:
|
||||
sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
|
||||
buf ? buf : &tail, output_size);
|
||||
if (unlikely(sz != output_size)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: wrote %zu bytes to command response"
|
||||
"but response size is %zu\n",
|
||||
__func__, sz, output_size);
|
||||
tail.status = VIRTIO_IOMMU_S_DEVERR;
|
||||
/*
|
||||
* We checked that sizeof(tail) can fit to elem->in_sg at the
|
||||
* beginning of the loop
|
||||
*/
|
||||
output_size = sizeof(tail);
|
||||
g_free(buf);
|
||||
buf = NULL;
|
||||
sz = iov_from_buf(elem->in_sg,
|
||||
elem->in_num,
|
||||
0,
|
||||
&tail,
|
||||
output_size);
|
||||
}
|
||||
assert(sz == output_size);
|
||||
|
||||
virtqueue_push(vq, elem, sz);
|
||||
|
Loading…
Reference in New Issue
Block a user