From: Farah Smith <[email protected]>

A missing return after a buffer size check allowed execution to fall
through into memcpy calls using firmware-controlled lengths, causing
an out-of-bounds read from the response buffer and potential overflow
of the caller's key, mask, and remap buffers.

Fix by returning immediately on error before any data is copied out.

Also validate that firmware-reported sizes are consistent with the
fixed-size response data array before copying, and ensure firmware
response sizes are converted to host byte order before use. Cast
result_size to size_t in the new bounds check to match key_size and
avoid a -Wsign-compare warning against the size_t from sizeof().

Fixes: 80317ff6adfd ("net/bnxt/tf_core: support Thor2")
Cc: [email protected]

Signed-off-by: Farah Smith <[email protected]>
Signed-off-by: Shahaji Bhosle <[email protected]>
Signed-off-by: Manish Kurup <[email protected]>
---
 drivers/net/bnxt/tf_core/v3/tfc_msg.c | 28 ++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/tf_core/v3/tfc_msg.c 
b/drivers/net/bnxt/tf_core/v3/tfc_msg.c
index cf72d09184..df11910dc3 100644
--- a/drivers/net/bnxt/tf_core/v3/tfc_msg.c
+++ b/drivers/net/bnxt/tf_core/v3/tfc_msg.c
@@ -1154,18 +1154,28 @@ tfc_msg_tcam_get(struct tfc *tfcp, uint16_t fid, 
uint16_t sid,
        rc = bnxt_hwrm_tf_message_direct(bp, false, HWRM_TFC_TCAM_GET,
                                         &req, sizeof(req), &resp, 
sizeof(resp));
 
-       if (rc ||
-           *key_size < rte_le_to_cpu_16(resp.key_size) ||
+       if (rc)
+               return rc;
+
+       if ((size_t)rte_le_to_cpu_16(resp.key_size) * 2 +
+           (size_t)rte_le_to_cpu_16(resp.result_size) > sizeof(resp.dev_data)) 
{
+               rc = -EINVAL;
+               PMD_DRV_LOG_LINE(ERR, "%s: FW sizes exceed TCAM bounds, rc:%d",
+                                __func__, rc);
+               return rc;
+       }
+       if (*key_size < rte_le_to_cpu_16(resp.key_size) ||
            *remap_size < rte_le_to_cpu_16(resp.result_size)) {
-               PMD_DRV_LOG_LINE(ERR, "Key buffer is too small, rc:%s",
-                                strerror(EINVAL));
                rc = -EINVAL;
+               PMD_DRV_LOG_LINE(ERR, "%s: Caller buffer too small, rc:%d",
+                                __func__, rc);
+               return rc;
        }
-       *key_size = resp.key_size;
-       *remap_size = resp.result_size;
-       memcpy(key, &resp.dev_data[0], resp.key_size);
-       memcpy(mask, &resp.dev_data[resp.key_size], resp.key_size);
-       memcpy(remap, &resp.dev_data[resp.key_size * 2], resp.result_size);
+       *key_size = rte_le_to_cpu_16(resp.key_size);
+       *remap_size = rte_le_to_cpu_16(resp.result_size);
+       memcpy(key, &resp.dev_data[0], *key_size);
+       memcpy(mask, &resp.dev_data[*key_size], *key_size);
+       memcpy(remap, &resp.dev_data[*key_size * 2], *remap_size);
 
        return rc;
 }
-- 
2.31.1

Reply via email to