- tests: bump QOS_PATH_MAX_ELEMENT_SIZE again - softmmu/physmem: fix memory leak in dirty_memory_extend() - crypto: run qcrypto_pbkdf2_count_iters in a new thread - hw/audio/virtio-sound: fix heap buffer overflow - hw/intc/arm_gic: fix spurious level triggered interrupts - ui/sdl2: set swap interval explicitly when OpenGL is enabled - target/riscv/kvm: tolerate KVM disable ext errors - virtio: remove virtio_tswap16s() call in vring_packed_event_read() - block: fix -Werror=maybe-uninitialized false-positive - hw/remote/vfio-user: Fix config space access byte order - hw/loongarch/virt: Fix memory leak - hw/intc/riscv_aplic: APLICs should add child earlier than realize - stdvga: fix screen blanking - ui/gtk: Draw guest frame at refresh cycle - target/i386: fix size of EBP writeback in gen_enter() - virtio-net: drop too short packets early - target/ppc: Fix lxv/stxv MSR facility check - target/ppc: Fix lxvx/stxvx facility check - virtio-snd: add max size bounds check in input cb(CVE-2024-7730) Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit e2eb79f1867bb8d8d870e758f06d2a32b3a4fc8a)
92 lines
3.0 KiB
Diff
92 lines
3.0 KiB
Diff
From 5651eb5cfd3a49506be4be97f8def3fed713c641 Mon Sep 17 00:00:00 2001
|
|
From: Alexey Dobriyan <adobriyan@yandex-team.ru>
|
|
Date: Tue, 30 Apr 2024 13:53:33 +0300
|
|
Subject: [PATCH] virtio-net: drop too short packets early
|
|
|
|
Reproducer from https://gitlab.com/qemu-project/qemu/-/issues/1451
|
|
creates small packet (1 segment, len = 10 == n->guest_hdr_len),
|
|
then destroys queue.
|
|
|
|
"if (n->host_hdr_len != n->guest_hdr_len)" is triggered, if body creates
|
|
zero length/zero segment packet as there is nothing after guest header.
|
|
|
|
qemu_sendv_packet_async() tries to send it.
|
|
|
|
slirp discards it because it is smaller than Ethernet header,
|
|
but returns 0 because tx hooks are supposed to return total length of data.
|
|
|
|
0 is propagated upwards and is interpreted as "packet has been sent"
|
|
which is terrible because queue is being destroyed, nobody is waiting for TX
|
|
to complete and assert it triggered.
|
|
|
|
Fix is discard such empty packets instead of sending them.
|
|
|
|
Length 1 packets will go via different codepath:
|
|
|
|
virtqueue_push(q->tx_vq, elem, 0);
|
|
virtio_notify(vdev, q->tx_vq);
|
|
g_free(elem);
|
|
|
|
and aren't problematic.
|
|
|
|
Signed-off-by: Alexey Dobriyan <adobriyan@yandex-team.ru>
|
|
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
|
(cherry picked from commit 2c3e4e2de699cd4d9f6c71f30a22d8f125cd6164)
|
|
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
|
|
---
|
|
hw/net/virtio-net.c | 18 ++++++++++++------
|
|
1 file changed, 12 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
|
|
index 432c433540..b17137a686 100644
|
|
--- a/hw/net/virtio-net.c
|
|
+++ b/hw/net/virtio-net.c
|
|
@@ -2732,18 +2732,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
|
|
out_sg = elem->out_sg;
|
|
if (out_num < 1) {
|
|
virtio_error(vdev, "virtio-net header not in first element");
|
|
- virtqueue_detach_element(q->tx_vq, elem, 0);
|
|
- g_free(elem);
|
|
- return -EINVAL;
|
|
+ goto detach;
|
|
}
|
|
|
|
if (n->has_vnet_hdr) {
|
|
if (iov_to_buf(out_sg, out_num, 0, &vhdr, 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;
|
|
+ goto detach;
|
|
}
|
|
if (n->needs_vnet_hdr_swap) {
|
|
virtio_net_hdr_swap(vdev, (void *) &vhdr);
|
|
@@ -2774,6 +2770,11 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
|
|
n->guest_hdr_len, -1);
|
|
out_num = sg_num;
|
|
out_sg = sg;
|
|
+
|
|
+ if (out_num < 1) {
|
|
+ virtio_error(vdev, "virtio-net nothing to send");
|
|
+ goto detach;
|
|
+ }
|
|
}
|
|
|
|
ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),
|
|
@@ -2794,6 +2795,11 @@ drop:
|
|
}
|
|
}
|
|
return num_packets;
|
|
+
|
|
+detach:
|
|
+ virtqueue_detach_element(q->tx_vq, elem, 0);
|
|
+ g_free(elem);
|
|
+ return -EINVAL;
|
|
}
|
|
|
|
static void virtio_net_tx_timer(void *opaque);
|
|
--
|
|
2.41.0.windows.1
|
|
|