Add bounds checking to prevent heap buffer overflow in
virtio_net_ctrl_pop(). The descriptor length is read twice from
guest-controlled shared memory - once to calculate allocation size
and once during memcpy. A malicious guest could modify the length
between reads to overflow the allocated buffer.

Track cumulative bytes copied and verify against allocated size
before each memcpy to ensure writes stay within bounds.

CVE-2026-86562
Bugzilla ID: 2003
Bugzilla ID: 2021

Cc: [email protected]

Reported-by: Ivar Al-Safawi <[email protected]>
Acked-by: Kevin Traynor <[email protected]>
Signed-off-by: Maxime Coquelin <[email protected]>
---
 lib/vhost/virtio_net_ctrl.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/vhost/virtio_net_ctrl.c b/lib/vhost/virtio_net_ctrl.c
index b059fe1f02..1e5034457c 100644
--- a/lib/vhost/virtio_net_ctrl.c
+++ b/lib/vhost/virtio_net_ctrl.c
@@ -138,6 +138,8 @@ virtio_net_ctrl_pop(struct virtio_net *dev, struct 
vhost_virtqueue *cvq,
 
        ctrl_req = (uint8_t *)ctrl_elem->ctrl_req;
 
+       uint64_t copied = 0;
+
        if (cvq->desc[desc_idx].flags & VRING_DESC_F_INDIRECT) {
                desc_len = cvq->desc[desc_idx].len;
                desc_iova = cvq->desc[desc_idx].addr;
@@ -175,8 +177,14 @@ virtio_net_ctrl_pop(struct virtio_net *dev, struct 
vhost_virtqueue *cvq,
                        goto free_err;
                }
 
+               if (copied + desc_len > data_len) {
+                       VHOST_CONFIG_LOG(dev->ifname, ERR, "Descriptor length 
overflow detected");
+                       goto free_err;
+               }
+
                memcpy(ctrl_req, (void *)(uintptr_t)desc_addr, desc_len);
                ctrl_req += desc_len;
+               copied += desc_len;
 
                if (!(descs[desc_idx].flags & VRING_DESC_F_NEXT))
                        break;
-- 
2.56.0

Reply via email to