From 069c7aceebcb79b58558c10de338ce4f80eb2241 Mon Sep 17 00:00:00 2001 From: Liu Long Date: Fri, 25 Sep 2020 13:41:25 +0800 Subject: [PATCH] dm: fix fault Injection into VirtIO console backend CVE# CVE-2021-23905 Add Null pointer check in init vq ring and add vq ring descriptor check in case cause Nullpointer exception. Tracked-On: #5355 Signed-off-by: Liu Long Reviewed-by: Wang, Yu1 --- devicemodel/core/vmmapi.c | 1 + devicemodel/hw/pci/virtio/virtio.c | 10 ++++++++++ devicemodel/hw/pci/virtio/virtio_console.c | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index 6a4b6c791..f8e02e12f 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -472,6 +472,7 @@ vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len) } } + pr_dbg("%s context memory is not valid!\n", __func__); return NULL; } diff --git a/devicemodel/hw/pci/virtio/virtio.c b/devicemodel/hw/pci/virtio/virtio.c index aebe6bf34..067fc3a66 100644 --- a/devicemodel/hw/pci/virtio/virtio.c +++ b/devicemodel/hw/pci/virtio/virtio.c @@ -342,18 +342,25 @@ virtio_vq_enable(struct virtio_base *base) phys = (((uint64_t)vq->gpa_desc[1]) << 32) | vq->gpa_desc[0]; size = qsz * sizeof(struct vring_desc); vb = paddr_guest2host(base->dev->vmctx, phys, size); + if (!vb) + goto error; vq->desc = (struct vring_desc *)vb; /* available ring */ phys = (((uint64_t)vq->gpa_avail[1]) << 32) | vq->gpa_avail[0]; size = (2 + qsz + 1) * sizeof(uint16_t); vb = paddr_guest2host(base->dev->vmctx, phys, size); + if (!vb) + goto error; + vq->avail = (struct vring_avail *)vb; /* used ring */ phys = (((uint64_t)vq->gpa_used[1]) << 32) | vq->gpa_used[0]; size = sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * qsz; vb = paddr_guest2host(base->dev->vmctx, phys, size); + if (!vb) + goto error; vq->used = (struct vring_used *)vb; /* Start at 0 when we use it. */ @@ -366,6 +373,9 @@ virtio_vq_enable(struct virtio_base *base) /* Mark queue as allocated after initialization is complete. */ mb(); vq->flags = VQ_ALLOC; + error: + vq->flags = 0; + pr_err("%s: vq enable failed\n", __func__); } /* diff --git a/devicemodel/hw/pci/virtio/virtio_console.c b/devicemodel/hw/pci/virtio/virtio_console.c index 32a3ca81e..592e54031 100644 --- a/devicemodel/hw/pci/virtio/virtio_console.c +++ b/devicemodel/hw/pci/virtio/virtio_console.c @@ -412,7 +412,9 @@ virtio_console_notify_rx(void *vdev, struct virtio_vq_info *vq) if (!port->rx_ready) { port->rx_ready = 1; - vq->used->flags |= VRING_USED_F_NO_NOTIFY; + if (vq_has_descs(vq)) { + vq->used->flags |= VRING_USED_F_NO_NOTIFY; + } } }