virtio-net checks that the "out" sg is longer than the guest header, but this check can be skipped if has_net_hdr is 0. Also perform this check if host_hdr_len != guest_hdr_len
Signed-off-by: Alexander Oleinik <alx...@bu.edu> --- hw/net/virtio-net.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index b9e1cd71cf..46d715b4f5 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2064,7 +2064,18 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) */ assert(n->host_hdr_len <= n->guest_hdr_len); if (n->host_hdr_len != n->guest_hdr_len) { - unsigned sg_num = iov_copy(sg, ARRAY_SIZE(sg), + unsigned sg_num; + + if (!n->has_vnet_hdr) { + if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) < + n->guest_hdr_len) { + virtio_error(vdev, "virtio-net header incorrect"); + virtqueue_detach_element(q->tx_vq, elem, 0); + g_free(elem); + return -EINVAL; + } + } + sg_num = iov_copy(sg, ARRAY_SIZE(sg), out_sg, out_num, 0, n->host_hdr_len); sg_num += iov_copy(sg + sg_num, ARRAY_SIZE(sg) - sg_num, -- 2.20.1