[pve-devel] [PATCH qemu 4/4] stable fixes for QEMU 9.1.2
Fiona Ebner
f.ebner at proxmox.com
Mon Nov 25 12:00:44 CET 2024
Pick up to stable fixes for virtio-net, one fixing multiqueue
initialization and one fixing potential out-of-bounds access (in the
work_around_broken_dhclient() hack that luckily seems to be
unreachable when 'vhost=on' is used for the device, which Proxmox VE
does except when running a non-native VM arch or if the vhost device
is not available).
Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
---
...o-net-Add-queues-before-loading-them.patch | 81 +++++++++++++++++++
...ix-size-check-in-dhclient-workaround.patch | 36 +++++++++
debian/patches/series | 2 +
3 files changed, 119 insertions(+)
create mode 100644 debian/patches/extra/0005-virtio-net-Add-queues-before-loading-them.patch
create mode 100644 debian/patches/extra/0006-virtio-net-Fix-size-check-in-dhclient-workaround.patch
diff --git a/debian/patches/extra/0005-virtio-net-Add-queues-before-loading-them.patch b/debian/patches/extra/0005-virtio-net-Add-queues-before-loading-them.patch
new file mode 100644
index 0000000..7369a49
--- /dev/null
+++ b/debian/patches/extra/0005-virtio-net-Add-queues-before-loading-them.patch
@@ -0,0 +1,81 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Akihiko Odaki <akihiko.odaki at daynix.com>
+Date: Tue, 22 Oct 2024 15:49:01 +0900
+Subject: [PATCH] virtio-net: Add queues before loading them
+
+Call virtio_net_set_multiqueue() to add queues before loading their
+states. Otherwise the loaded queues will not have handlers and elements
+in them will not be processed.
+
+Cc: qemu-stable at nongnu.org
+Fixes: 8c49756825da ("virtio-net: Add only one queue pair when realizing")
+Reported-by: Laurent Vivier <lvivier at redhat.com>
+Signed-off-by: Akihiko Odaki <akihiko.odaki at daynix.com>
+Acked-by: Michael S. Tsirkin <mst at redhat.com>
+(picked from https://lore.kernel.org/qemu-devel/20241022-load-v1-1-99df0bff7939@daynix.com/)
+Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
+---
+ hw/net/virtio-net.c | 10 ++++++++++
+ hw/virtio/virtio.c | 7 +++++++
+ include/hw/virtio/virtio.h | 2 ++
+ 3 files changed, 19 insertions(+)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index ed33a32877..90d05f94d4 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -3032,6 +3032,15 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
+ virtio_net_set_queue_pairs(n);
+ }
+
++static int virtio_net_pre_load_queues(VirtIODevice *vdev)
++{
++ virtio_net_set_multiqueue(VIRTIO_NET(vdev),
++ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_RSS) ||
++ virtio_has_feature(vdev->guest_features, VIRTIO_NET_F_MQ));
++
++ return 0;
++}
++
+ static int virtio_net_post_load_device(void *opaque, int version_id)
+ {
+ VirtIONet *n = opaque;
+@@ -4010,6 +4019,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
+ vdc->guest_notifier_mask = virtio_net_guest_notifier_mask;
+ vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;
+ vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO);
++ vdc->pre_load_queues = virtio_net_pre_load_queues;
+ vdc->post_load = virtio_net_post_load_virtio;
+ vdc->vmsd = &vmstate_virtio_net_device;
+ vdc->primary_unplug_pending = primary_unplug_pending;
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 9e10cbc058..10f24a58dd 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -3251,6 +3251,13 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
+ config_len--;
+ }
+
++ if (vdc->pre_load_queues) {
++ ret = vdc->pre_load_queues(vdev);
++ if (ret) {
++ return ret;
++ }
++ }
++
+ num = qemu_get_be32(f);
+
+ if (num > VIRTIO_QUEUE_MAX) {
+diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
+index 0fcbc5c0c6..953dfca27c 100644
+--- a/include/hw/virtio/virtio.h
++++ b/include/hw/virtio/virtio.h
+@@ -210,6 +210,8 @@ struct VirtioDeviceClass {
+ void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
+ int (*start_ioeventfd)(VirtIODevice *vdev);
+ void (*stop_ioeventfd)(VirtIODevice *vdev);
++ /* Called before loading queues. Useful to add queues before loading. */
++ int (*pre_load_queues)(VirtIODevice *vdev);
+ /* Saving and loading of a device; trying to deprecate save/load
+ * use vmsd for new devices.
+ */
diff --git a/debian/patches/extra/0006-virtio-net-Fix-size-check-in-dhclient-workaround.patch b/debian/patches/extra/0006-virtio-net-Fix-size-check-in-dhclient-workaround.patch
new file mode 100644
index 0000000..29df2c1
--- /dev/null
+++ b/debian/patches/extra/0006-virtio-net-Fix-size-check-in-dhclient-workaround.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Akihiko Odaki <akihiko.odaki at daynix.com>
+Date: Fri, 22 Nov 2024 14:03:08 +0900
+Subject: [PATCH] virtio-net: Fix size check in dhclient workaround
+
+work_around_broken_dhclient() accesses IP and UDP headers to detect
+relevant packets and to calculate checksums, but it didn't check if
+the packet has size sufficient to accommodate them, causing out-of-bound
+access hazards. Fix this by correcting the size requirement.
+
+Fixes: 1d41b0c1ec66 ("Work around dhclient brokenness")
+Cc: qemu-stable at nongnu.org
+Signed-off-by: Akihiko Odaki <akihiko.odaki at daynix.com>
+(picked from https://lore.kernel.org/qemu-devel/20241122-queue-v3-2-f2ff03b8dbfd@daynix.com/#t)
+Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
+---
+ hw/net/virtio-net.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 90d05f94d4..c1fe457359 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -1692,8 +1692,11 @@ static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr)
+ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
+ uint8_t *buf, size_t size)
+ {
++ size_t csum_size = ETH_HLEN + sizeof(struct ip_header) +
++ sizeof(struct udp_header);
++
+ if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
+- (size > 27 && size < 1500) && /* normal sized MTU */
++ (size >= csum_size && size < 1500) && /* normal sized MTU */
+ (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
+ (buf[23] == 17) && /* ip.protocol == UDP */
+ (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
diff --git a/debian/patches/series b/debian/patches/series
index 3b57a3a..0b48878 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,6 +2,8 @@ extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch
extra/0002-scsi-megasas-Internal-cdbs-have-16-byte-length.patch
extra/0003-ide-avoid-potential-deadlock-when-draining-during-tr.patch
extra/0004-Revert-x86-acpi-workaround-Windows-not-handling-name.patch
+extra/0005-virtio-net-Add-queues-before-loading-them.patch
+extra/0006-virtio-net-Fix-size-check-in-dhclient-workaround.patch
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
--
2.39.5
More information about the pve-devel
mailing list