diff options
-rw-r--r-- | hw/net/virtio-net.c | 18 | ||||
-rw-r--r-- | include/hw/virtio/virtio.h | 2 |
2 files changed, 18 insertions, 2 deletions
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 8b32339b76..aba12759d5 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -549,7 +549,14 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) { VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + NetClientState *nc; + + /* validate queue_index and skip for cvq */ + if (queue_index >= n->max_queue_pairs * 2) { + return; + } + + nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); if (!nc->peer) { return; @@ -566,9 +573,16 @@ static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index) static void virtio_net_queue_enable(VirtIODevice *vdev, uint32_t queue_index) { VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + NetClientState *nc; int r; + /* validate queue_index and skip for cvq */ + if (queue_index >= n->max_queue_pairs * 2) { + return; + } + + nc = qemu_get_subqueue(n->nic, vq2q(queue_index)); + if (!nc->peer || !vdev->vhost_started) { return; } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 141a253a2c..a973811cbf 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -148,7 +148,9 @@ struct VirtioDeviceClass { void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); void (*set_status)(VirtIODevice *vdev, uint8_t val); + /* Device must validate queue_index. */ void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); + /* Device must validate queue_index. */ void (*queue_enable)(VirtIODevice *vdev, uint32_t queue_index); /* For transitional devices, this is a bitmap of features * that are only exposed on the legacy interface but not |