From 33487238055e1ea92086256be2aac2bdef1de012 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Fri, 2 Jul 2021 12:03:06 +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 Signed-off-by: Yonghua Huang Reviewed-by: Wang, Yu1 --- devicemodel/hw/pci/virtio/virtio.c | 11 +++++++++++ devicemodel/hw/pci/virtio/virtio_console.c | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/devicemodel/hw/pci/virtio/virtio.c b/devicemodel/hw/pci/virtio/virtio.c index be49083b5..8e6feccec 100644 --- a/devicemodel/hw/pci/virtio/virtio.c +++ b/devicemodel/hw/pci/virtio/virtio.c @@ -332,18 +332,26 @@ 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; /* Mark queue as allocated, and start at 0 when we use it. */ @@ -353,6 +361,9 @@ virtio_vq_enable(struct virtio_base *base) /* Mark queue as enabled. */ vq->enabled = true; + +error: + vq->flags = 0; } /* diff --git a/devicemodel/hw/pci/virtio/virtio_console.c b/devicemodel/hw/pci/virtio/virtio_console.c index a964e590c..e28ed21cf 100644 --- a/devicemodel/hw/pci/virtio/virtio_console.c +++ b/devicemodel/hw/pci/virtio/virtio_console.c @@ -405,7 +405,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; + } } }