From: Joseph Wong <[email protected]>
Add bounds checking in bnxt_get_nvram_directory() to prevent a length
underflow when subtracting 2 from the input length, and an integer
overflow when calculating the required buffer length. Also enforce
firmware-supplied upper bounds on the directory entry count and entry
length, guarding against an undersized DMA buffer if firmware reports
implausible values, and use 64-bit arithmetic for the buffer size
calculation. The two returned values are each written back as a
single byte, so their upper bounds are UINT8_MAX, not larger values
that would let a firmware-reported value above 255 pass validation
and then silently truncate on the byte store.
Fixes: 19e6af01bb36 ("net/bnxt: support get/set EEPROM")
Cc: [email protected]
Signed-off-by: Joseph Wong <[email protected]>
Signed-off-by: Farah Smith <[email protected]>
Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
drivers/net/bnxt/bnxt_hwrm.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1615b36aae..bb55de9905 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -6049,6 +6049,9 @@ int bnxt_hwrm_nvm_get_dir_info(struct bnxt *bp, uint32_t
*entries,
return rc;
}
+#define BNXT_MAX_DIR_ENTRIES UINT8_MAX
+#define BNXT_MAX_ENTRY_LENGTH UINT8_MAX
+
int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data)
{
int rc;
@@ -6060,16 +6063,27 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t
len, uint8_t *data)
struct hwrm_nvm_get_dir_entries_input req = {0};
struct hwrm_nvm_get_dir_entries_output *resp = bp->hwrm_cmd_resp_addr;
+ if (len < 2)
+ return -EINVAL;
+
rc = bnxt_hwrm_nvm_get_dir_info(bp, &dir_entries, &entry_length);
if (rc != 0)
return rc;
+ if (dir_entries == 0 || dir_entries > BNXT_MAX_DIR_ENTRIES ||
+ entry_length == 0 || entry_length > BNXT_MAX_ENTRY_LENGTH) {
+ PMD_DRV_LOG_LINE(ERR,
+ "Invalid dir info: entries=%u length=%u",
+ dir_entries, entry_length);
+ return -EINVAL;
+ }
+
*data++ = dir_entries;
*data++ = entry_length;
len -= 2;
memset(data, 0xff, len);
- buflen = dir_entries * entry_length;
+ buflen = (size_t)dir_entries * entry_length;
buf = rte_malloc("nvm_dir", buflen, 0);
if (buf == NULL)
return -ENOMEM;
--
2.47.3