[PATCH 2/5] common/cnxk: fix TM schq alloc OOB write

Aarnav JP ajp at marvell.com
Mon Nov 2 13:21:50 CET 2026


nix_tm_copy_rsp_to_nix() consumes the txsch alloc response verbatim.
The count rsp->schq[lvl] is not bounded to the 128-entry list, so a
large count over-reads schq_list[lvl][]; and the schq id is passed
to plt_bitmap_set() as the bit position without checking it against
NIX_TM_MAX_HW_TXSCHQ (2048). rte_bitmap_set() does not bound-check
pos, so an id >= 2048 writes outside the bitmap and corrupts memory.

Clamp the count to MAX_TXSCHQ_PER_FUNC and reject any id >=
NIX_TM_MAX_HW_TXSCHQ with -EINVAL, propagating the error out of
nix_tm_alloc_txschq() so setup fails cleanly. Applied to both the
discontiguous and contiguous lists.

Fixes: df405df95eeb ("common/cnxk: add NIX TM helper to alloc/free resource")
Cc: stable at dpdk.org

Signed-off-by: Aarnav JP <ajp at marvell.com>
---
 drivers/common/cnxk/roc_nix_priv.h   |  2 +-
 drivers/common/cnxk/roc_nix_tm.c     | 37 ++++++++++++++++++++++------
 drivers/common/cnxk/roc_nix_tm_ops.c |  8 ++++--
 3 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/common/cnxk/roc_nix_priv.h b/drivers/common/cnxk/roc_nix_priv.h
index d4b3c7c1af..9779b336b0 100644
--- a/drivers/common/cnxk/roc_nix_priv.h
+++ b/drivers/common/cnxk/roc_nix_priv.h
@@ -421,7 +421,7 @@ int nix_tm_alloc_txschq(struct nix *nix, enum roc_nix_tm_tree tree);
 int nix_tm_assign_resources(struct nix *nix, enum roc_nix_tm_tree tree);
 int nix_tm_release_resources(struct nix *nix, uint8_t hw_lvl, bool contig,
 			     bool above_thresh);
-void nix_tm_copy_rsp_to_nix(struct nix *nix, struct nix_txsch_alloc_rsp *rsp);
+int nix_tm_copy_rsp_to_nix(struct nix *nix, struct nix_txsch_alloc_rsp *rsp);
 
 int nix_tm_txsch_reg_config(struct nix *nix, enum roc_nix_tm_tree tree);
 int nix_tm_update_parent_info(struct nix *nix, enum roc_nix_tm_tree tree);
diff --git a/drivers/common/cnxk/roc_nix_tm.c b/drivers/common/cnxk/roc_nix_tm.c
index 76c0f01884..2f38b042f9 100644
--- a/drivers/common/cnxk/roc_nix_tm.c
+++ b/drivers/common/cnxk/roc_nix_tm.c
@@ -1483,21 +1483,40 @@ nix_tm_assign_resources(struct nix *nix, enum roc_nix_tm_tree tree)
 	return 0;
 }
 
-void
+int
 nix_tm_copy_rsp_to_nix(struct nix *nix, struct nix_txsch_alloc_rsp *rsp)
 {
 	uint8_t lvl;
 	uint16_t i;
 
 	for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
-		for (i = 0; i < rsp->schq[lvl]; i++)
-			plt_bitmap_set(nix->schq_bmp[lvl],
-				       rsp->schq_list[lvl][i]);
 
-		for (i = 0; i < rsp->schq_contig[lvl]; i++)
-			plt_bitmap_set(nix->schq_contig_bmp[lvl],
-				       rsp->schq_contig_list[lvl][i]);
+		uint16_t cnt = PLT_MIN(rsp->schq[lvl], (uint16_t)MAX_TXSCHQ_PER_FUNC);
+
+		for (i = 0; i < cnt; i++) {
+			uint16_t id = rsp->schq_list[lvl][i];
+
+			if (id >= NIX_TM_MAX_HW_TXSCHQ) {
+				plt_err("Invalid schq %u for lvl %u in alloc rsp", id, lvl);
+				return -EINVAL;
+			}
+			plt_bitmap_set(nix->schq_bmp[lvl], id);
+		}
+
+		cnt = PLT_MIN(rsp->schq_contig[lvl], (uint16_t)MAX_TXSCHQ_PER_FUNC);
+
+		for (i = 0; i < cnt; i++) {
+			uint16_t id = rsp->schq_contig_list[lvl][i];
+
+			if (id >= NIX_TM_MAX_HW_TXSCHQ) {
+				plt_err("Invalid contig schq %u for lvl %u in alloc rsp", id, lvl);
+				return -EINVAL;
+			}
+			plt_bitmap_set(nix->schq_contig_bmp[lvl], id);
+		}
 	}
+
+	return 0;
 }
 
 int
@@ -1563,8 +1582,10 @@ nix_tm_alloc_txschq(struct nix *nix, enum roc_nix_tm_tree tree)
 			goto alloc_err;
 		}
 
-		nix_tm_copy_rsp_to_nix(nix, rsp);
+		rc = nix_tm_copy_rsp_to_nix(nix, rsp);
 		mbox_put(mbox);
+		if (rc)
+			goto alloc_err;
 	} while (pend);
 
 	nix->tm_link_cfg_lvl = rsp->link_cfg_lvl;
diff --git a/drivers/common/cnxk/roc_nix_tm_ops.c b/drivers/common/cnxk/roc_nix_tm_ops.c
index 230e9b72f6..1086f471e6 100644
--- a/drivers/common/cnxk/roc_nix_tm_ops.c
+++ b/drivers/common/cnxk/roc_nix_tm_ops.c
@@ -778,8 +778,10 @@ roc_nix_tm_prealloc_res(struct roc_nix *roc_nix, uint8_t lvl,
 			return rc;
 		}
 
-		nix_tm_copy_rsp_to_nix(nix, rsp);
+		rc = nix_tm_copy_rsp_to_nix(nix, rsp);
 		mbox_put(mbox);
+		if (rc)
+			return rc;
 	}
 
 	/* Preallocate contiguous */
@@ -797,8 +799,10 @@ roc_nix_tm_prealloc_res(struct roc_nix *roc_nix, uint8_t lvl,
 			return rc;
 		}
 
-		nix_tm_copy_rsp_to_nix(nix, rsp);
+		rc = nix_tm_copy_rsp_to_nix(nix, rsp);
 		mbox_put(mbox);
+		if (rc)
+			return rc;
 	}
 
 	/* Save thresholds */
-- 
2.43.0



More information about the stable mailing list