]>
Commit | Line | Data |
---|---|---|
3dcc8d3b | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
c25a2220 WB |
2 | From: Prasad J Pandit <pjp@fedoraproject.org> |
3 | Date: Wed, 29 Nov 2017 23:14:27 +0530 | |
3dcc8d3b | 4 | Subject: [PATCH] virtio: check VirtQueue Vring object is set |
c25a2220 WB |
5 | |
6 | A guest could attempt to use an uninitialised VirtQueue object | |
7 | or unset Vring.align leading to a arithmetic exception. Add check | |
8 | to avoid it. | |
9 | ||
10 | Reported-by: Zhangboxian <zhangboxian@huawei.com> | |
11 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | |
12 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> | |
13 | Signed-off-by: Michael S. Tsirkin <mst@redhat.com> | |
14 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | |
15 | Reviewed-by: Cornelia Huck <cohuck@redhat.com> | |
16 | --- | |
17 | hw/virtio/virtio.c | 14 +++++++++++--- | |
18 | 1 file changed, 11 insertions(+), 3 deletions(-) | |
19 | ||
20 | diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c | |
21 | index 33bb770177..76b9a9907c 100644 | |
22 | --- a/hw/virtio/virtio.c | |
23 | +++ b/hw/virtio/virtio.c | |
24 | @@ -183,7 +183,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n) | |
25 | { | |
26 | VRing *vring = &vdev->vq[n].vring; | |
27 | ||
28 | - if (!vring->desc) { | |
29 | + if (!vring->num || !vring->desc || !vring->align) { | |
30 | /* not yet setup -> nothing to do */ | |
31 | return; | |
32 | } | |
33 | @@ -1416,6 +1416,9 @@ void virtio_config_modern_writel(VirtIODevice *vdev, | |
34 | ||
35 | void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr) | |
36 | { | |
37 | + if (!vdev->vq[n].vring.num) { | |
38 | + return; | |
39 | + } | |
40 | vdev->vq[n].vring.desc = addr; | |
41 | virtio_queue_update_rings(vdev, n); | |
42 | } | |
43 | @@ -1428,6 +1431,9 @@ hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n) | |
44 | void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc, | |
45 | hwaddr avail, hwaddr used) | |
46 | { | |
47 | + if (!vdev->vq[n].vring.num) { | |
48 | + return; | |
49 | + } | |
50 | vdev->vq[n].vring.desc = desc; | |
51 | vdev->vq[n].vring.avail = avail; | |
52 | vdev->vq[n].vring.used = used; | |
53 | @@ -1496,8 +1502,10 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align) | |
54 | */ | |
55 | assert(k->has_variable_vring_alignment); | |
56 | ||
57 | - vdev->vq[n].vring.align = align; | |
58 | - virtio_queue_update_rings(vdev, n); | |
59 | + if (align) { | |
60 | + vdev->vq[n].vring.align = align; | |
61 | + virtio_queue_update_rings(vdev, n); | |
62 | + } | |
63 | } | |
64 | ||
65 | static bool virtio_queue_notify_aio_vq(VirtQueue *vq) | |
66 | -- | |
67 | 2.11.0 | |
68 |