Blob Blame Raw
From 30860f89b8dc79b24906e8f7d6d6aa0788616bd1 Mon Sep 17 00:00:00 2001
From: Xiao Wang <jasowang@redhat.com>
Date: Thu, 18 Jan 2018 08:16:16 +0100
Subject: [PATCH 1/3] virtio-net: validate backend queue numbers against bus
 limitation

RH-Author: Xiao Wang <jasowang@redhat.com>
Message-id: <1516263376-6261-1-git-send-email-jasowang@redhat.com>
Patchwork-id: 78662
O-Subject: [RHEL7.5 qemu-kvm PATCH] virtio-net: validate backend queue numbers against bus limitation
Bugzilla: 1460872
RH-Acked-by: wexu@redhat.com
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>

Notes: conflict since RHEL7 lacks:
- 575a1c0e4228 ("net: move queue number into NICPeers")
- e6f746b380ad ("virtio-net: Convert to QOM realize")

We don't validate the backend queue numbers against bus limitation,
this will easily crash qemu if it exceeds the limitation which will
hit the abort() in virtio_del_queue(). An example is trying to
starting a virtio-net device with 256 queues. E.g:

./qemu-system-x86_64 -netdev tap,id=hn0,queues=256 -device
virtio-net-pci,netdev=hn0

Fixing this by doing the validation and fail early.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 7e0e736ecdfeac6d3517513d3a702304e4f6cf59)
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>

Conflicts:
	hw/net/virtio-net.c
---
 hw/net/virtio-net.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index eb2feaf..3e41acc 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1535,6 +1535,14 @@ static int virtio_net_device_init(VirtIODevice *vdev)
                                   n->config_size);
 
     n->max_queues = MAX(n->nic_conf.queues, 1);
+    if (n->max_queues * 2 + 1 > VIRTIO_PCI_QUEUE_MAX) {
+        error_report("Invalid number of queues (= %" PRIu32 "), "
+                   "must be a postive integer less than %d.",
+                   n->max_queues, (VIRTIO_PCI_QUEUE_MAX - 1) / 2);
+        virtio_cleanup(vdev);
+        return -EINVAL;
+    }
+
     n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);
     n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);
     n->curr_queues = 1;
-- 
1.8.3.1