Thread (2 messages) 2 messages, 2 authors, 8h ago
HOTtoday

[PATCH] net: bnx2x: validate firmware section bounds without overflow

From: Pengpeng Hou <hidden>
Date: 2026-07-06 09:34:14
Also in: lkml
Subsystem: broadcom bnx2x 10 gigabit ethernet driver, networking drivers, the rest · Maintainers: Sudarsana Kalluru, Manish Chopra, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

The firmware loader validates each section with offset + length before it
uses section offsets to read data from the firmware image. Both fields are
32-bit values from the firmware header, so the addition can wrap before it
is compared with the firmware size.

Validate sections as offset <= size and length <= size - offset instead.
Also require the firmware version section to contain the four bytes that
bnx2x_check_firmware() reads later.

Signed-off-by: Pengpeng Hou <redacted>
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 208a894d6190..c756a639e6ee 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -13258,6 +13258,11 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
 	return rc;
 }
 
+static bool bnx2x_fw_section_valid(size_t fw_size, u32 offset, u32 len)
+{
+	return offset <= fw_size && len <= fw_size - offset;
+}
+
 static int bnx2x_check_firmware(struct bnx2x *bp)
 {
 	const struct firmware *firmware = bp->firmware;
@@ -13281,7 +13286,7 @@ static int bnx2x_check_firmware(struct bnx2x *bp)
 	for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
 		offset = be32_to_cpu(sections[i].offset);
 		len = be32_to_cpu(sections[i].len);
-		if (offset + len > firmware->size) {
+		if (!bnx2x_fw_section_valid(firmware->size, offset, len)) {
 			BNX2X_ERR("Section %d length is out of bounds\n", i);
 			return -EINVAL;
 		}
@@ -13300,6 +13305,11 @@ static int bnx2x_check_firmware(struct bnx2x *bp)
 	}
 
 	/* Check FW version */
+	if (be32_to_cpu(fw_hdr->fw_version.len) < 4) {
+		BNX2X_ERR("FW version section is too small\n");
+		return -EINVAL;
+	}
+
 	offset = be32_to_cpu(fw_hdr->fw_version.offset);
 	fw_ver = firmware->data + offset;
 	if (fw_ver[0] != bp->fw_major || fw_ver[1] != bp->fw_minor ||
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help