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

