Right now too short packet from guest triggers assert in iov_copy(). (because requested offset does not fit into io vector)
For legacy virtio without feature VIRTIO_F_ANY_LAYOUT virtio-net header must fit exactly in the first descriptor. With features VIRTIO_F_ANY_LAYOUT or VIRTIO_F_VERSION_1 header is usually fused with data but sides must support any arbitrary layout, so header may not fit into first descriptor. Present check verifies only count of descriptors, which isn't helpful. Let's check total length to intercept such short packets. Alternative solution is removing asserts from io vector helpers and checking results of copying from io vector where needed. Buglink: https://gitlab.com/qemu-project/qemu/-/issues/762 Signed-off-by: Konstantin Khlebnikov <[email protected]> --- hw/net/virtio-net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index cf8ab0f8af..b47f70076d 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2533,8 +2533,8 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) out_num = elem->out_num; out_sg = elem->out_sg; - if (out_num < 1) { - virtio_error(vdev, "virtio-net header not in first element"); + if (iov_size(out_sg, out_num) < n->guest_hdr_len) { + virtio_error(vdev, "virtio-net header is missing"); virtqueue_detach_element(q->tx_vq, elem, 0); g_free(elem); return -EINVAL;
