[RFC] vhost/crypto: fix descriptor index validation

Stephen Hemminger stephen at networkplumber.org
Thu Mar 26 02:43:12 CET 2026


The descriptor index from the available ring was not validated and
was re-read from shared memory in the finalize path. Save the
descriptor index at fetch time, validate it, and use a compiler
barrier to prevent reloading from shared memory.

Fixes: 3bb595ecd682 ("vhost/crypto: add request handler")
Cc: stable at dpdk.org

Reported-by: Adiel Sol <adiel.sol at dream-security.com>
Reported-by: Arad Inbar <arad.inbar at dream-security.com>
Reported-by: Erez Cohen <erez.cohen at dream-security.com>
Reported-by: Nir Somech <nir.somech at dream-security.com>
Reported-by: Ben Grinberg <ben.grinberg at dream-security.com>
Reported-by: Daniel Lubel <daniel.lubel at dream-security.com>
Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
This patch was generated by usin AI to analyze bug report.
IT HAS NOT BEEN TESTED.

 lib/vhost/vhost_crypto.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/lib/vhost/vhost_crypto.c b/lib/vhost/vhost_crypto.c
index 648e2d731b..f1d3702070 100644
--- a/lib/vhost/vhost_crypto.c
+++ b/lib/vhost/vhost_crypto.c
@@ -242,6 +242,7 @@ struct vhost_crypto_data_req {
 	struct vhost_virtqueue *vq;
 	struct vhost_crypto_writeback_data *wb;
 	struct rte_mempool *wb_pool;
+	uint16_t used_idx;
 	uint16_t desc_idx;
 	uint16_t len;
 	uint16_t zero_copy;
@@ -1486,7 +1487,7 @@ static __rte_always_inline int
 vhost_crypto_process_one_req(struct vhost_crypto *vcrypto,
 		struct vhost_virtqueue *vq, struct rte_crypto_op *op,
 		struct vring_desc *head, struct vhost_crypto_desc *descs,
-		uint16_t desc_idx)
+		uint16_t used_idx, uint16_t desc_idx)
 	__rte_requires_shared_capability(&vq->iotlb_lock)
 {
 	struct vhost_crypto_data_req *vc_req, *vc_req_out;
@@ -1504,6 +1505,7 @@ vhost_crypto_process_one_req(struct vhost_crypto *vcrypto,
 	int err;
 
 	vc_req = &data_req;
+	vc_req->used_idx = used_idx;
 	vc_req->desc_idx = desc_idx;
 	vc_req->dev = vcrypto->dev;
 	vc_req->vq = vq;
@@ -1725,7 +1727,8 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op,
 		return NULL;
 	}
 	vq = vc_req->vq;
-	used_idx = vc_req->desc_idx;
+	used_idx = vc_req->used_idx;
+	desc_idx = vc_req->desc_idx;
 
 	if (old_vq && (vq != old_vq))
 		return vq;
@@ -1737,9 +1740,8 @@ vhost_crypto_finalize_one_request(struct rte_crypto_op *op,
 			write_back_data(vc_req);
 	}
 
-	desc_idx = vq->avail->ring[used_idx];
-	vq->used->ring[desc_idx].id = vq->avail->ring[desc_idx];
-	vq->used->ring[desc_idx].len = vc_req->len;
+	vq->used->ring[used_idx].id = desc_idx;
+	vq->used->ring[used_idx].len = vc_req->len;
 
 	if (op->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
 		rte_mempool_put(m_src->pool, (void *)m_src);
@@ -2044,16 +2046,24 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid,
 		for (i = 0; i < count; i++) {
 			uint16_t used_idx = (start_idx + i) & (vq->size - 1);
 			uint16_t desc_idx = vq->avail->ring[used_idx];
-			struct vring_desc *head = &vq->desc[desc_idx];
+			struct vring_desc *head;
 			struct rte_crypto_op *op = ops[i];
 
+			rte_compiler_barrier();
+			if (unlikely(desc_idx >= vq->size)) {
+				VC_LOG_ERR("Invalid descriptor index %u",
+					   desc_idx);
+				break;
+			}
+			head = &vq->desc[desc_idx];
+
 			op->sym->m_src = mbufs[i * 2];
 			op->sym->m_dst = mbufs[i * 2 + 1];
 			op->sym->m_src->data_off = 0;
 			op->sym->m_dst->data_off = 0;
 
 			if (unlikely(vhost_crypto_process_one_req(vcrypto, vq,
-					op, head, descs, used_idx) < 0))
+					op, head, descs, used_idx, desc_idx) < 0))
 				break;
 		}
 
@@ -2074,15 +2084,23 @@ rte_vhost_crypto_fetch_requests(int vid, uint32_t qid,
 		for (i = 0; i < count; i++) {
 			uint16_t used_idx = (start_idx + i) & (vq->size - 1);
 			uint16_t desc_idx = vq->avail->ring[used_idx];
-			struct vring_desc *head = &vq->desc[desc_idx];
+			struct vring_desc *head;
 			struct rte_crypto_op *op = ops[i];
 
+			rte_compiler_barrier();
+			if (unlikely(desc_idx >= vq->size)) {
+				VC_LOG_ERR("Invalid descriptor index %u",
+					   desc_idx);
+				break;
+			}
+			head = &vq->desc[desc_idx];
+
 			op->sym->m_src = mbufs[i];
 			op->sym->m_dst = NULL;
 			op->sym->m_src->data_off = 0;
 
 			if (unlikely(vhost_crypto_process_one_req(vcrypto, vq,
-					op, head, descs, desc_idx) < 0))
+					op, head, descs, used_idx, desc_idx) < 0))
 				break;
 		}
 
-- 
2.53.0



More information about the stable mailing list