[PATCH 08/16] crypto/cnxk: reject oversized SG vectors in raw datapath

Tejasree Kondoj ktejasree at marvell.com
Mon Oct 19 15:07:49 CEST 2026


From: Rupesh Chiluka <rchiluka at marvell.com>

In raw datapath, iov builders copied application-supplied SG entries
into the fixed-size iov->src[]/dst[] stack buffers (max ROC_MAX_SG_CNT
entries) without validating the segment count. A raw-dp crypto vector
with more than ROC_MAX_SG_CNT segments results in a stack overwrite.

Reject vector lists whose src_sgl[].num, dest_sgl[].num, or n_data_vecs
exceed ROC_MAX_SG_CNT before copying.

cnxk_raw_burst_to_iov() and cnxk_raw_to_iov() now return an error,
which is propagated by the cn10k and cn20k raw enqueue paths to fail
the op cleanly.

Signed-off-by: Rupesh Chiluka <rchiluka at marvell.com>
---
 drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 29 ++++++++++++++++++-----
 drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 29 ++++++++++++++++++-----
 drivers/crypto/cnxk/cnxk_se.h             | 23 ++++++++++++++++--
 3 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index 870e65c049..bf273774fd 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -1615,17 +1615,30 @@ cn10k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym
 		infl_req = &pend_q->req_queue[head];
 		infl_req->op_flags = 0;
 
-		cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+		ret = cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+		if (unlikely(ret != 0)) {
+			plt_dp_err("Failed to convert raw to iov: %d", index);
+			if (i == 0 && count == 0) {
+				*enqueue_status = ret;
+				return 0;
+			} else if (i == 0) {
+				goto pend_q_commit;
+			} else {
+				break;
+			}
+		}
 		ret = cn10k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[i], infl_req,
 					      user_data[index], is_sgv2);
 		if (unlikely(ret != 1)) {
 			plt_dp_err("Could not process vec: %d", index);
-			if (i == 0 && count == 0)
-				return -1;
-			else if (i == 0)
+			if (i == 0 && count == 0) {
+				*enqueue_status = -EINVAL;
+				return 0;
+			} else if (i == 0) {
 				goto pend_q_commit;
-			else
+			} else {
 				break;
+			}
 		}
 		pending_queue_advance(&head, pq_mask);
 	}
@@ -1694,7 +1707,11 @@ cn10k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data
 	if (unlikely(nb_allowed == 0))
 		return -1;
 
-	cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+	ret = cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+	if (unlikely(ret != 0)) {
+		plt_dp_err("Failed to convert raw to iov");
+		return -1;
+	}
 
 	lmt_base = qp->lmtline.lmt_base;
 	io_addr = qp->lmtline.io_addr;
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index a63b97654b..7707755775 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -1189,17 +1189,30 @@ cn20k_cpt_raw_enqueue_burst(void *qpair, uint8_t *drv_ctx, struct rte_crypto_sym
 		infl_req = &pend_q->req_queue[head];
 		infl_req->op_flags = 0;
 
-		cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+		ret = cnxk_raw_burst_to_iov(vec, &ofs, index, &iov);
+		if (unlikely(ret != 0)) {
+			plt_dp_err("Failed to convert raw to iov: %d", index);
+			if (i == 0 && count == 0) {
+				*enqueue_status = ret;
+				return 0;
+			} else if (i == 0) {
+				goto pend_q_commit;
+			} else {
+				break;
+			}
+		}
 		ret = cn20k_cpt_raw_fill_inst(&iov, qp, dp_ctx, &inst[i], infl_req,
 					      user_data[index]);
 		if (unlikely(ret != 1)) {
 			plt_dp_err("Could not process vec: %d", index);
-			if (i == 0 && count == 0)
-				return -1;
-			else if (i == 0)
+			if (i == 0 && count == 0) {
+				*enqueue_status = -EINVAL;
+				return 0;
+			} else if (i == 0) {
 				goto pend_q_commit;
-			else
+			} else {
 				break;
+			}
 		}
 		pending_queue_advance(&head, pq_mask);
 	}
@@ -1249,7 +1262,11 @@ cn20k_cpt_raw_enqueue(void *qpair, uint8_t *drv_ctx, struct rte_crypto_vec *data
 	if (unlikely(nb_allowed == 0))
 		return -1;
 
-	cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+	ret = cnxk_raw_to_iov(data_vec, n_data_vecs, &ofs, iv, digest, aad_or_auth_iv, &iov);
+	if (unlikely(ret != 0)) {
+		plt_dp_err("Failed to convert raw to iov");
+		return -1;
+	}
 
 	lmt_base = qp->lmtline.lmt_base;
 	io_addr = qp->lmtline.io_addr;
diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h
index 505a5fcd37..b712acdccd 100644
--- a/drivers/crypto/cnxk/cnxk_se.h
+++ b/drivers/crypto/cnxk/cnxk_se.h
@@ -3633,10 +3633,19 @@ prepare_iov_from_raw_vec(struct rte_crypto_vec *vec, struct roc_se_iov_ptr *iove
 	return total_len;
 }
 
-static __rte_always_inline void
+static __rte_always_inline int
 cnxk_raw_burst_to_iov(struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs *ofs, int index,
 		      struct cnxk_iov *iov)
 {
+	uint32_t dst_num =
+		(vec->dest_sgl == NULL) ? vec->src_sgl[index].num : vec->dest_sgl[index].num;
+
+	if (unlikely(vec->src_sgl[index].num > ROC_MAX_SG_CNT || dst_num > ROC_MAX_SG_CNT)) {
+		plt_dp_err("Number of segments (src: %u, dst: %u) exceeds max supported (%u)",
+			   vec->src_sgl[index].num, dst_num, ROC_MAX_SG_CNT);
+		return -ENOTSUP;
+	}
+
 	iov->iv_buf = vec->iv[index].va;
 	iov->aad_buf = vec->aad[index].va;
 	iov->mac_buf = vec->digest[index].va;
@@ -3658,13 +3667,21 @@ cnxk_raw_burst_to_iov(struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs *
 
 	iov->a_head = ofs->ofs.auth.head;
 	iov->a_tail = ofs->ofs.auth.tail;
+
+	return 0;
 }
 
-static __rte_always_inline void
+static __rte_always_inline int
 cnxk_raw_to_iov(struct rte_crypto_vec *data_vec, uint16_t n_vecs, union rte_crypto_sym_ofs *ofs,
 		struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
 		struct rte_crypto_va_iova_ptr *aad, struct cnxk_iov *iov)
 {
+	if (unlikely(n_vecs > ROC_MAX_SG_CNT)) {
+		plt_dp_err("Number of segments (%u) exceeds max supported (%u)", n_vecs,
+			   ROC_MAX_SG_CNT);
+		return -ENOTSUP;
+	}
+
 	iov->iv_buf = iv->va;
 	iov->aad_buf = aad->va;
 	iov->mac_buf = digest->va;
@@ -3678,6 +3695,8 @@ cnxk_raw_to_iov(struct rte_crypto_vec *data_vec, uint16_t n_vecs, union rte_cryp
 
 	iov->a_head = ofs->ofs.auth.head;
 	iov->a_tail = ofs->ofs.auth.tail;
+
+	return 0;
 }
 
 static inline void
-- 
2.43.0



More information about the dev mailing list