[PATCH v3 10/10] crypto/cnxk: fix tls mbuf sanity failures

Tejasree Kondoj ktejasree at marvell.com
Mon Sep 29 11:43:53 CEST 2025


From: Nithinsen Kaithakadan <nkaithakadan at marvell.com>

Fix mbuf sanity check failure by zeroing data_len of each
segment from the target len onward and adjusting pkt_len
in the head mbuf. Hence by avoiding call to free mbuf from
intermediate node.

Fixes: 9a126e7cf088 ("crypto/cnxk: support TLS padding verification")
Fixes: c05eb27d55d8 ("crypto/cnxk: add CN20K TLS post-process")
Cc: stable at dpdk.org

Signed-off-by: Nithinsen Kaithakadan <nkaithakadan at marvell.com>
---
 drivers/crypto/cnxk/cn10k_cryptodev_ops.c | 40 ++++++++---------------
 drivers/crypto/cnxk/cn20k_cryptodev_ops.c | 39 +++++++---------------
 drivers/crypto/cnxk/cnxk_cryptodev_ops.h  | 26 +++++++++++++++
 3 files changed, 51 insertions(+), 54 deletions(-)

diff --git a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
index d6b95a14aa..870e65c049 100644
--- a/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn10k_cryptodev_ops.c
@@ -931,13 +931,13 @@ cn10k_cpt_ipsec_post_process(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *
 static inline void
 cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res, uint8_t mac_len)
 {
-	struct rte_mbuf *mac_prev_seg = NULL, *mac_seg = NULL, *seg;
 	uint32_t pad_len, trim_len, mac_offset, pad_offset;
 	struct rte_mbuf *mbuf = cop->sym->m_src;
-	uint16_t m_len = res->rlen;
-	uint32_t i, nb_segs = 1;
+	uint16_t m_len = res->rlen, len_to_trim;
+	struct rte_mbuf *seg;
 	uint8_t pad_res = 0;
 	uint8_t pad_val;
+	uint32_t i;
 
 	pad_val = ((res->spi >> 16) & 0xff);
 	pad_len = pad_val + 1;
@@ -966,11 +966,8 @@ cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
 	seg = mbuf;
 	while (mac_offset >= seg->data_len) {
 		mac_offset -= seg->data_len;
-		mac_prev_seg = seg;
 		seg = seg->next;
-		nb_segs++;
 	}
-	mac_seg = seg;
 
 	pad_offset = mac_offset + mac_len;
 	while (pad_offset >= seg->data_len) {
@@ -995,17 +992,9 @@ cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
 		cop->aux_flags = res->uc_compcode;
 	}
 
-	mbuf->pkt_len = m_len - trim_len;
-	if (mac_offset) {
-		rte_pktmbuf_free(mac_seg->next);
-		mac_seg->next = NULL;
-		mac_seg->data_len = mac_offset;
-		mbuf->nb_segs = nb_segs;
-	} else {
-		rte_pktmbuf_free(mac_seg);
-		mac_prev_seg->next = NULL;
-		mbuf->nb_segs = nb_segs - 1;
-	}
+	len_to_trim = mbuf->pkt_len - (m_len - trim_len);
+
+	pktmbuf_trim_chain(mbuf, len_to_trim);
 }
 
 /* TLS-1.3:
@@ -1016,11 +1005,11 @@ cn10k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res,
 static inline void
 cn10k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
 {
+	uint16_t m_len = res->rlen, len_to_trim;
 	struct rte_mbuf *mbuf = cop->sym->m_src;
 	struct rte_mbuf *seg = mbuf;
-	uint16_t m_len = res->rlen;
 	uint8_t *ptr, type = 0x0;
-	int len, i, nb_segs = 1;
+	int len, i;
 
 	while (m_len && !type) {
 		len = m_len;
@@ -1030,7 +1019,6 @@ cn10k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
 		while (len > seg->data_len) {
 			len -= seg->data_len;
 			seg = seg->next;
-			nb_segs++;
 		}
 
 		/* walkthrough from last until a non zero value is found */
@@ -1043,16 +1031,14 @@ cn10k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn10k_res_s *res)
 		m_len -= len;
 	}
 
+	len_to_trim = mbuf->pkt_len - i;
+
 	if (type) {
+		pktmbuf_trim_chain(mbuf, len_to_trim);
 		cop->param1.tls_record.content_type = type;
-		mbuf->pkt_len = m_len + i;
-		mbuf->nb_segs = nb_segs;
-		seg->data_len = i;
-		rte_pktmbuf_free(seg->next);
-		seg->next = NULL;
-	} else {
+
+	} else
 		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
-	}
 }
 
 static inline void
diff --git a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
index b696c28081..1803e4ba5a 100644
--- a/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
+++ b/drivers/crypto/cnxk/cn20k_cryptodev_ops.c
@@ -896,13 +896,13 @@ cn20k_cpt_ipsec_post_process(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *
 static inline void
 cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res, uint8_t mac_len)
 {
-	struct rte_mbuf *mac_prev_seg = NULL, *mac_seg = NULL, *seg;
 	uint32_t pad_len, trim_len, mac_offset, pad_offset;
 	struct rte_mbuf *mbuf = cop->sym->m_src;
-	uint16_t m_len = res->rlen;
-	uint32_t i, nb_segs = 1;
+	uint16_t m_len = res->rlen, len_to_trim;
+	struct rte_mbuf *seg;
 	uint8_t pad_res = 0;
 	uint8_t pad_val;
+	uint32_t i;
 
 	pad_val = ((res->spi >> 16) & 0xff);
 	pad_len = pad_val + 1;
@@ -931,11 +931,8 @@ cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res,
 	seg = mbuf;
 	while (mac_offset >= seg->data_len) {
 		mac_offset -= seg->data_len;
-		mac_prev_seg = seg;
 		seg = seg->next;
-		nb_segs++;
 	}
-	mac_seg = seg;
 
 	pad_offset = mac_offset + mac_len;
 	while (pad_offset >= seg->data_len) {
@@ -960,17 +957,9 @@ cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res,
 		cop->aux_flags = res->uc_compcode;
 	}
 
-	mbuf->pkt_len = m_len - trim_len;
-	if (mac_offset) {
-		rte_pktmbuf_free(mac_seg->next);
-		mac_seg->next = NULL;
-		mac_seg->data_len = mac_offset;
-		mbuf->nb_segs = nb_segs;
-	} else {
-		rte_pktmbuf_free(mac_seg);
-		mac_prev_seg->next = NULL;
-		mbuf->nb_segs = nb_segs - 1;
-	}
+	len_to_trim = mbuf->pkt_len - (m_len - trim_len);
+
+	pktmbuf_trim_chain(mbuf, len_to_trim);
 }
 
 /* TLS-1.3:
@@ -981,11 +970,11 @@ cn20k_cpt_tls12_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res,
 static inline void
 cn20k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res)
 {
+	uint16_t m_len = res->rlen, len_to_trim;
 	struct rte_mbuf *mbuf = cop->sym->m_src;
 	struct rte_mbuf *seg = mbuf;
-	uint16_t m_len = res->rlen;
 	uint8_t *ptr, type = 0x0;
-	int len, i, nb_segs = 1;
+	int len, i;
 
 	while (m_len && !type) {
 		len = m_len;
@@ -995,7 +984,6 @@ cn20k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res)
 		while (len > seg->data_len) {
 			len -= seg->data_len;
 			seg = seg->next;
-			nb_segs++;
 		}
 
 		/* walkthrough from last until a non zero value is found */
@@ -1008,16 +996,13 @@ cn20k_cpt_tls13_trim_mac(struct rte_crypto_op *cop, struct cpt_cn20k_res_s *res)
 		m_len -= len;
 	}
 
+	len_to_trim = mbuf->pkt_len - i;
+
 	if (type) {
+		pktmbuf_trim_chain(mbuf, len_to_trim);
 		cop->param1.tls_record.content_type = type;
-		mbuf->pkt_len = m_len + i;
-		mbuf->nb_segs = nb_segs;
-		seg->data_len = i;
-		rte_pktmbuf_free(seg->next);
-		seg->next = NULL;
-	} else {
+	} else
 		cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
-	}
 }
 
 static inline void
diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
index 17d39aa34f..02223fbf3a 100644
--- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
+++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.h
@@ -239,4 +239,30 @@ cnxk_cpt_sec_inst_w7_get(struct roc_cpt *roc_cpt, void *cptr)
 
 	return w7.u64;
 }
+
+static inline void
+pktmbuf_trim_chain(struct rte_mbuf *m, uint16_t len)
+{
+	uint16_t len_so_far = 0, left_over = 0, new_mlen;
+	struct rte_mbuf *cur = m;
+
+	new_mlen = m->pkt_len - len;
+
+	while (len_so_far < new_mlen) {
+		left_over = new_mlen - len_so_far;
+		if (left_over < cur->data_len)
+			break;
+		len_so_far += cur->data_len;
+		cur = cur->next;
+	}
+
+	cur->data_len = left_over;
+	cur = cur->next;
+	while (cur) {
+		cur->data_len = 0;
+		cur = cur->next;
+	}
+
+	m->pkt_len = new_mlen;
+}
 #endif /* _CNXK_CRYPTODEV_OPS_H_ */
-- 
2.25.1



More information about the dev mailing list