Add bounds checking against inflight table size in split and packed ring inflight descriptor APIs. The inflight table is sized from queue_size received in VHOST_USER_SET_INFLIGHT_FD, but the guest can later resize the virtqueue larger via SET_VRING_NUM. Existing checks only validated against vq->size, not the inflight table's desc_num.
A malicious guest could desynchronize these sizes and publish avail entries with head indices valid for the enlarged virtqueue but out of bounds for the inflight descriptor table, causing heap corruption. CVE-2026-86565 Bugzilla ID: 2008 Cc: [email protected] Reported-by: m'te'a physical <[email protected]> Acked-by: Kevin Traynor <[email protected]> Signed-off-by: Maxime Coquelin <[email protected]> --- lib/vhost/vhost.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index 2d694d586e..918e50ed43 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -1149,6 +1149,9 @@ rte_vhost_set_inflight_desc_split(int vid, uint16_t vring_idx, if (unlikely(idx >= vq->size)) return -1; + if (unlikely(idx >= vq->inflight_split->desc_num)) + return -1; + vq->inflight_split->desc[idx].counter = vq->global_counter++; vq->inflight_split->desc[idx].inflight = 1; return 0; @@ -1196,6 +1199,9 @@ rte_vhost_set_inflight_desc_packed(int vid, uint16_t vring_idx, if (unlikely(old_free_head >= vq->size)) return -1; + if (unlikely(old_free_head >= inflight_info->desc_num)) + return -1; + free_head = old_free_head; /* init header descriptor */ @@ -1255,6 +1261,9 @@ rte_vhost_clr_inflight_desc_split(int vid, uint16_t vring_idx, if (unlikely(idx >= vq->size)) return -1; + if (unlikely(idx >= vq->inflight_split->desc_num)) + return -1; + rte_atomic_thread_fence(rte_memory_order_seq_cst); vq->inflight_split->desc[idx].inflight = 0; @@ -1299,6 +1308,9 @@ rte_vhost_clr_inflight_desc_packed(int vid, uint16_t vring_idx, if (unlikely(head >= vq->size)) return -1; + if (unlikely(head >= inflight_info->desc_num)) + return -1; + rte_atomic_thread_fence(rte_memory_order_seq_cst); inflight_info->desc[head].inflight = 0; @@ -1383,10 +1395,16 @@ rte_vhost_set_last_inflight_io_packed(int vid, uint16_t vring_idx, if (unlikely(head >= vq->size)) return -1; + if (unlikely(head >= inflight_info->desc_num)) + return -1; + last = inflight_info->desc[head].last; if (unlikely(last >= vq->size)) return -1; + if (unlikely(last >= inflight_info->desc_num)) + return -1; + inflight_info->desc[last].next = inflight_info->free_head; inflight_info->free_head = head; inflight_info->used_idx += inflight_info->desc[head].num; -- 2.56.0

