|
|
9ae3a8 |
From acb67d9c43f3921861eebbabb447a85644e99320 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 25 Jul 2016 12:55:36 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 2/2] virtio: error out if guest exceeds virtqueue size
|
|
|
9ae3a8 |
MIME-Version: 1.0
|
|
|
9ae3a8 |
Content-Type: text/plain; charset=UTF-8
|
|
|
9ae3a8 |
Content-Transfer-Encoding: 8bit
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1469451336-20117-2-git-send-email-stefanha@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 71428
|
|
|
9ae3a8 |
O-Subject: [virt-devel] [RHEL-7.3 EMBARGOED qemu-kvm PATCH 1/1] virtio: error out if guest exceeds virtqueue size
|
|
|
9ae3a8 |
Bugzilla: 1359729
|
|
|
9ae3a8 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Marc-André Lureau <mlureau@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
A broken or malicious guest can submit more requests than the virtqueue
|
|
|
9ae3a8 |
size permits.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The guest can submit requests without bothering to wait for completion
|
|
|
9ae3a8 |
and is therefore not bound by virtqueue size. This requires reusing
|
|
|
9ae3a8 |
vring descriptors in more than one request, which is incorrect but
|
|
|
9ae3a8 |
possible. Processing a request allocates a VirtQueueElement and
|
|
|
9ae3a8 |
therefore causes unbounded memory allocation controlled by the guest.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Exit with an error if the guest provides more requests than the
|
|
|
9ae3a8 |
virtqueue size permits. This bounds memory allocation and makes the
|
|
|
9ae3a8 |
buggy guest visible to the user.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This patch fixes CVE-2016-5403.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
hw/virtio/virtio.c | 5 +++++
|
|
|
9ae3a8 |
1 file changed, 5 insertions(+)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
|
|
9ae3a8 |
index 132b5af..a861870 100644
|
|
|
9ae3a8 |
--- a/hw/virtio/virtio.c
|
|
|
9ae3a8 |
+++ b/hw/virtio/virtio.c
|
|
|
9ae3a8 |
@@ -452,6 +452,11 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
max = vq->vring.num;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ if (vq->inuse >= max) {
|
|
|
9ae3a8 |
+ error_report("Virtqueue size exceeded");
|
|
|
9ae3a8 |
+ exit(1);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
|
|
|
9ae3a8 |
if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
|
|
|
9ae3a8 |
vring_avail_event(vq, vring_avail_idx(vq));
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|