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 <caojinhua1@huawei.com>
This commit is contained in:
parent
c7155d3353
commit
c86cebdfb5
52
virtio-bugfix-clean-up-callback-when-del-virtqueue.patch
Normal file
52
virtio-bugfix-clean-up-callback-when-del-virtqueue.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 95d334a905e8ddaac4a8cec908dcdb03b2e5993f Mon Sep 17 00:00:00 2001
|
||||
From: Jinhua Cao <caojinhua1@huawei.com>
|
||||
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 <caojinhua1@huawei.com>
|
||||
---
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user