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: [email protected]
Signed-off-by: Aarnav JP <[email protected]>
---
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