From c86cebdfb5d00797230ac1c1ff10a5c6a06cd22b Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 10:17:20 +0800 Subject: [PATCH] virtio: bugfix: clean up callback when del virtqueue We will access NULL pointer as follow: 1. Start a vm with multiqueue vhost-net 2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to trigger multiqueue disable in this vm which will delete the virtqueue. In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh still exist. 3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh will be called and qemu will be crashed. Signed-off-by: Jinhua Cao --- ...clean-up-callback-when-del-virtqueue.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 virtio-bugfix-clean-up-callback-when-del-virtqueue.patch diff --git a/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch b/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch new file mode 100644 index 0000000..c0e259b --- /dev/null +++ b/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch @@ -0,0 +1,52 @@ +From 95d334a905e8ddaac4a8cec908dcdb03b2e5993f Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 10:17:20 +0800 +Subject: [PATCH] virtio: bugfix: clean up callback when del virtqueue + +We will access NULL pointer as follow: +1. Start a vm with multiqueue vhost-net +2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to + trigger multiqueue disable in this vm which will delete the virtqueue. + In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh + still exist. +3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to + notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh + will be called and qemu will be crashed. + +Signed-off-by: Jinhua Cao +--- + hw/net/virtio-net.c | 5 ++++- + hw/virtio/virtio.c | 1 + + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index f2014d5ea0..b3a5d0b19e 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -2644,7 +2644,10 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq) + return; + } + virtio_queue_set_notification(vq, 0); +- qemu_bh_schedule(q->tx_bh); ++ ++ if (q->tx_bh) { ++ qemu_bh_schedule(q->tx_bh); ++ } + } + + static void virtio_net_tx_timer(void *opaque) +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 9b4ac58a16..ec3e96af3b 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2417,6 +2417,7 @@ void virtio_delete_queue(VirtQueue *vq) + { + vq->vring.num = 0; + vq->vring.num_default = 0; ++ vq->vring.align = 0; + vq->handle_output = NULL; + vq->handle_aio_output = NULL; + g_free(vq->used_elems); +-- +2.27.0 +