5d360b
From 30860f89b8dc79b24906e8f7d6d6aa0788616bd1 Mon Sep 17 00:00:00 2001
5d360b
From: Xiao Wang <jasowang@redhat.com>
5d360b
Date: Thu, 18 Jan 2018 08:16:16 +0100
5d360b
Subject: [PATCH 1/3] virtio-net: validate backend queue numbers against bus
5d360b
 limitation
5d360b
5d360b
RH-Author: Xiao Wang <jasowang@redhat.com>
5d360b
Message-id: <1516263376-6261-1-git-send-email-jasowang@redhat.com>
5d360b
Patchwork-id: 78662
5d360b
O-Subject: [RHEL7.5 qemu-kvm PATCH] virtio-net: validate backend queue numbers against bus limitation
5d360b
Bugzilla: 1460872
5d360b
RH-Acked-by: wexu@redhat.com
5d360b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
5d360b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
5d360b
Notes: conflict since RHEL7 lacks:
5d360b
- 575a1c0e4228 ("net: move queue number into NICPeers")
5d360b
- e6f746b380ad ("virtio-net: Convert to QOM realize")
5d360b
5d360b
We don't validate the backend queue numbers against bus limitation,
5d360b
this will easily crash qemu if it exceeds the limitation which will
5d360b
hit the abort() in virtio_del_queue(). An example is trying to
5d360b
starting a virtio-net device with 256 queues. E.g:
5d360b
5d360b
./qemu-system-x86_64 -netdev tap,id=hn0,queues=256 -device
5d360b
virtio-net-pci,netdev=hn0
5d360b
5d360b
Fixing this by doing the validation and fail early.
5d360b
5d360b
Cc: Michael S. Tsirkin <mst@redhat.com>
5d360b
Cc: qemu-stable <qemu-stable@nongnu.org>
5d360b
Signed-off-by: Jason Wang <jasowang@redhat.com>
5d360b
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
5d360b
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
5d360b
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5d360b
(cherry picked from commit 7e0e736ecdfeac6d3517513d3a702304e4f6cf59)
5d360b
Signed-off-by: Jason Wang <jasowang@redhat.com>
5d360b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
5d360b
Conflicts:
5d360b
	hw/net/virtio-net.c
5d360b
---
5d360b
 hw/net/virtio-net.c | 8 ++++++++
5d360b
 1 file changed, 8 insertions(+)
5d360b
5d360b
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
5d360b
index eb2feaf..3e41acc 100644
5d360b
--- a/hw/net/virtio-net.c
5d360b
+++ b/hw/net/virtio-net.c
5d360b
@@ -1535,6 +1535,14 @@ static int virtio_net_device_init(VirtIODevice *vdev)
5d360b
                                   n->config_size);
5d360b
 
5d360b
     n->max_queues = MAX(n->nic_conf.queues, 1);
5d360b
+    if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) {
5d360b
+        error_report("Invalid number of queues (= %" PRIu32 "), "
5d360b
+                   "must be a postive integer less than %d.",
5d360b
+                   n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2);
5d360b
+        virtio_cleanup(vdev);
5d360b
+        return -EINVAL;
5d360b
+    }
5d360b
+
5d360b
     n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
5d360b
     n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
5d360b
     n->curr_queues = 1;
5d360b
-- 
5d360b
1.8.3.1
5d360b