From: Rupesh Chiluka <[email protected]>

The TLS decrypt tail-fetch path for CBC/3DES READ sessions computed the
tail-fetch source offset as (pkt_len - tail_len) without checking that
pkt_len >= tail_len. For an inbound record shorter than tail_len, the
subtraction underflows when passed as the uint32_t offset to
rte_pktmbuf_read(), which then returns NULL because offset + len
exceeds the packet length. The following rte_memcpy(in_buffer, output,
tail_len) dereferences that NULL pointer.

Reject records with pkt_len < tail_len (return -EINVAL) before computing
the tail-fetch offset in the scatter-gather branches of process_tls_read()
for both cn10k (SGv1 and SGv2) and cn20k.

Signed-off-by: Rupesh Chiluka <[email protected]>
---
 drivers/crypto/cnxk/cn10k_tls_ops.h | 12 ++++++++++++
 drivers/crypto/cnxk/cn20k_tls_ops.h |  6 ++++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/crypto/cnxk/cn10k_tls_ops.h 
b/drivers/crypto/cnxk/cn10k_tls_ops.h
index 90600bd850..416207f676 100644
--- a/drivers/crypto/cnxk/cn10k_tls_ops.h
+++ b/drivers/crypto/cnxk/cn10k_tls_ops.h
@@ -260,6 +260,12 @@ process_tls_read(struct rte_crypto_op *cop, struct 
cn10k_sec_session *sess,
                uint32_t dlen;
                int i;
 
+               if (unlikely(pkt_len < tail_len)) {
+                       plt_dp_err("Invalid TLS record: pkt_len %d < tail_len 
%d", pkt_len,
+                                  tail_len);
+                       return -EINVAL;
+               }
+
                if (unlikely(m_src->nb_segs > ROC_SG1_MAX_PTRS)) {
                        plt_dp_err("Exceeds max supported components. Reduce 
segments");
                        return -1;
@@ -320,6 +326,12 @@ process_tls_read(struct rte_crypto_op *cop, struct 
cn10k_sec_session *sess,
                uint32_t g_size_bytes;
                int i;
 
+               if (unlikely(pkt_len < tail_len)) {
+                       plt_dp_err("Invalid TLS record: pkt_len %d < tail_len 
%d", pkt_len,
+                                  tail_len);
+                       return -EINVAL;
+               }
+
                if (unlikely(m_src->nb_segs > ROC_SG2_MAX_PTRS)) {
                        plt_dp_err("Exceeds max supported components. Reduce 
segments");
                        return -1;
diff --git a/drivers/crypto/cnxk/cn20k_tls_ops.h 
b/drivers/crypto/cnxk/cn20k_tls_ops.h
index e7a8ba34ae..670acbe9ab 100644
--- a/drivers/crypto/cnxk/cn20k_tls_ops.h
+++ b/drivers/crypto/cnxk/cn20k_tls_ops.h
@@ -203,6 +203,12 @@ process_tls_read(struct rte_crypto_op *cop, struct 
cn20k_sec_session *sess,
                uint32_t g_size_bytes;
                int i;
 
+               if (unlikely(pkt_len < tail_len)) {
+                       plt_dp_err("Invalid TLS record: pkt_len %d < tail_len 
%d", pkt_len,
+                                  tail_len);
+                       return -EINVAL;
+               }
+
                if (unlikely(m_src->nb_segs > ROC_SG2_MAX_PTRS)) {
                        plt_dp_err("Exceeds max supported components. Reduce 
segments");
                        return -1;
-- 
2.43.0

Reply via email to