From: Nithinsen Kaithakadan <[email protected]>

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: [email protected]

Signed-off-by: Nithinsen Kaithakadan <[email protected]>
---
 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

Reply via email to