[PATCH 24.11 12/14] vhost: fix inflight descriptor table overflow

Maxime Coquelin maxime.coquelin at redhat.com
Wed Oct 14 17:01:52 CEST 2026


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

Reported-by: Jia Jia <physicalmtea at gmail.com>
Acked-by: Kevin Traynor <ktraynor at redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin at redhat.com>
---
 lib/vhost/vhost.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c
index 489d11193a..835f5dfb11 100644
--- a/lib/vhost/vhost.c
+++ b/lib/vhost/vhost.c
@@ -1160,6 +1160,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;
@@ -1206,6 +1209,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 */
@@ -1264,6 +1270,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;
@@ -1307,6 +1316,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;
@@ -1389,10 +1401,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



More information about the stable mailing list