[PATCH v3 1/4] bus/dpaa: fix out-of-bounds read of mac_idx array

From
Gagandeep Singh <hidden>
Date
2026-11-03 09:36:15
Reply to
Gagandeep Singh, 2026-11-03
fman_if_init() and fman_if_init_onic() read the devicetree
'cell-index' property and store it unchecked into
__if->__if.mac_idx. This value is later used as an index into the
fixed-size mac_idx[] lookup table in fman_if_vsp_init(), so a
cell-index value greater than or equal to the number of entries in
that table results in an out-of-bounds read.

Add an explicit upper-bound check (FMAN_MAX_MAC_IDX_NUM) in both
fman_if_init() and fman_if_init_onic() before the mac_idx assignment,
and a static_assert in fman_if_vsp_init() to keep mac_idx[] in sync
with FMAN_MAX_MAC_IDX_NUM if it is ever resized.

Also remove the unused MEMMAC_REG_OFFSET() macro from fman.h, which
had no remaining callers.

Fixes: a0edbb8a8e52 ("bus/dpaa: add OH port mode")
Fixes: 7e5f49ae767d ("bus/dpaa: add ONIC port mode")
Cc: <redacted>

Signed-off-by: Gagandeep Singh <redacted>
---
 drivers/bus/dpaa/base/fman/fman.c | 19 +++++++++++++++++++
 drivers/bus/dpaa/include/fman.h   |  6 +++++-
 drivers/net/dpaa/dpaa_flow.c      |  5 ++++-
 3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index 67f77265ca..223cd6958d 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -205,6 +205,9 @@ static void fman_if_vsp_init(struct __fman_if *__if)
 	size_t lenp;
 	const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
 
+	static_assert(RTE_DIM(mac_idx) == FMAN_MAX_MAC_IDX_NUM,
+		      "mac_idx[] out of sync with FMAN_MAX_MAC_IDX_NUM");
+
 	if (__if->__if.mac_idx <= 8) {
 		for_each_compatible_node(dev, NULL,
 			"fsl,fman-port-1g-rx-extended-args") {
@@ -544,6 +547,14 @@ fman_if_init(const struct device_node *dpa_node, int fd)
 		cell_idx_host = of_read_number(cell_idx,
 					       lenp / sizeof(phandle));
 
+		if (cell_idx_host >= FMAN_MAX_MAC_IDX_NUM) {
+			FMAN_ERR(-EINVAL,
+				 "%s: cell-index(%" PRIu64 ") >= max(%d)",
+				 oh_node->full_name, cell_idx_host,
+				 FMAN_MAX_MAC_IDX_NUM);
+			goto err;
+		}
+
 		__if->__if.mac_idx = cell_idx_host;
 	}
 
@@ -957,6 +968,14 @@ static int fman_if_init_onic(const struct device_node *dpa_node)
 	assert(lenp == sizeof(*cell_idx));
 
 	cell_idx_host = of_read_number(cell_idx, lenp / sizeof(phandle));
+
+	if (cell_idx_host >= FMAN_MAX_MAC_IDX_NUM) {
+		FMAN_ERR(-EINVAL, "%s: cell-index(%" PRIu64 ") >= max(%d)",
+			 tx_oh_node->full_name, cell_idx_host,
+			 FMAN_MAX_MAC_IDX_NUM);
+		goto err;
+	}
+
 	__if->__if.mac_idx = cell_idx_host;
 
 	fman_node = of_get_parent(fman_tx_oh_node);
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index f642faf3b3..030c85c284 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -68,6 +68,11 @@
 #define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES	4
 #define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS	3
 
+/*
+ * Maximum number of MAC/offline port indexes.
+ */
+#define FMAN_MAX_MAC_IDX_NUM	11
+
 /* Represents the different flavour of network interface */
 enum fman_mac_type {
 	fman_offline_internal = 0,
@@ -475,7 +480,6 @@ struct __fman_if {
 	void *qmi_map;
 };
 
-#define MEMMAC_REG_OFFSET(reg) offsetof(struct memac_regs, reg)
 #define BMI_RX_REG_OFFSET(reg) offsetof(struct rx_bmi_regs, reg)
 #define BMI_TX_REG_OFFSET(reg) offsetof(struct tx_bmi_regs, reg)
 
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index f77f9f333b..403e97ed2d 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -32,9 +32,12 @@ return &scheme_params->param.key_ext_and_hash.extract_array[hdr_idx];
 	SCH_EXT_HDR(scheme_params, hdr_idx).extract_by_hdr_type.full_field
 
 /* FMAN mac indexes mappings (0 is unused, first 8 are for 1G, next for 10G
- * ports).
+ * ports). Indexed by fman_if.mac_idx, which the bus validates against
+ * FMAN_MAX_MAC_IDX_NUM when deriving it from the device tree.
  */
 static const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
+static_assert(RTE_DIM(mac_idx) == FMAN_MAX_MAC_IDX_NUM,
+	"mac_idx[] out of sync with FMAN_MAX_MAC_IDX_NUM");
 
 /* FM global info */
 struct dpaa_fm_info {
-- 
2.25.1
Thread (21 messages) 21 messages, 2 authors, last reply 2d ago
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help