The branch main has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=3de231b4d956f7b9c22e31f75805030a417f7bf3
commit 3de231b4d956f7b9c22e31f75805030a417f7bf3 Author: Zhenlei Huang <z...@freebsd.org> AuthorDate: 2025-02-14 10:38:29 +0000 Commit: Zhenlei Huang <z...@freebsd.org> CommitDate: 2025-02-14 10:38:29 +0000 bnxt_en: Retrieve maximum of 128 APP TLVs It appears that the maximum number of APP TLVs supported by the hardware is 128 according to D45005. Well Daniel Porsch reported an issue PR284073 which shows that the number can exceed the limit, causing out of bound write to on-stack allocated variable app[128] and the kernel panics. Limit to 128 while retrieving APP TLVs. PR: 284073 Reviewed by: markj Tested by: Daniel Porsch <daniel.por...@loopia.se> Fixes: 35b53f8c989f bnxt_en: Add PFC, ETS & App TLVs protocols support MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D48589 --- sys/dev/bnxt/bnxt_en/bnxt.h | 3 ++- sys/dev/bnxt/bnxt_en/bnxt_dcb.c | 17 ++++++++++------- sys/dev/bnxt/bnxt_en/bnxt_mgmt.c | 1 + sys/dev/bnxt/bnxt_en/bnxt_sysctl.c | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h index e4f866807070..b0c3a8913622 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt.h +++ b/sys/dev/bnxt/bnxt_en/bnxt.h @@ -1310,6 +1310,7 @@ int bnxt_dcb_ieee_getpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc); int bnxt_dcb_ieee_setpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc); int bnxt_dcb_ieee_setapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app); int bnxt_dcb_ieee_delapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app); -int bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs); +int bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, + size_t nitems, int *num_inputs); #endif /* _BNXT_H */ diff --git a/sys/dev/bnxt/bnxt_en/bnxt_dcb.c b/sys/dev/bnxt/bnxt_en/bnxt_dcb.c index e1e0581d3c24..e0643f200021 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_dcb.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_dcb.c @@ -313,7 +313,8 @@ bnxt_hwrm_queue_pfc_qcfg(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc) } static int -bnxt_hwrm_get_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs) +bnxt_hwrm_get_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app, + size_t nitems, int *num_inputs) { struct hwrm_fw_get_structured_data_input get = {0}; struct hwrm_struct_data_dcbx_app *fw_app; @@ -350,7 +351,7 @@ bnxt_hwrm_get_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int * } n = data->count; - for (i = 0; i < n; i++, fw_app++) { + for (i = 0; i < n && *num_inputs < nitems; i++, fw_app++) { app[*num_inputs].priority = fw_app->priority; app[*num_inputs].protocol = htobe16(fw_app->protocol_id); app[*num_inputs].selector = fw_app->protocol_selector; @@ -472,7 +473,8 @@ bnxt_hwrm_queue_dscp_qcaps(struct bnxt_softc *softc) } static int -bnxt_hwrm_queue_dscp2pri_qcfg(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs) +bnxt_hwrm_queue_dscp2pri_qcfg(struct bnxt_softc *softc, struct bnxt_dcb_app *app, + size_t nitems, int *num_inputs) { struct hwrm_queue_dscp2pri_qcfg_input req = {0}; struct hwrm_queue_dscp2pri_qcfg_output *resp = @@ -503,7 +505,7 @@ bnxt_hwrm_queue_dscp2pri_qcfg(struct bnxt_softc *softc, struct bnxt_dcb_app *app goto end; entry_cnt = le16toh(resp->entry_cnt); - for (i = 0; i < entry_cnt; i++) { + for (i = 0; i < entry_cnt && *num_inputs < nitems; i++) { app[*num_inputs].priority = dscp2pri[i].pri; app[*num_inputs].protocol = dscp2pri[i].dscp; app[*num_inputs].selector = BNXT_IEEE_8021QAZ_APP_SEL_DSCP; @@ -774,10 +776,11 @@ bnxt_dcb_ieee_delapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app) } int -bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, int *num_inputs) +bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app, + size_t nitems, int *num_inputs) { - bnxt_hwrm_get_dcbx_app(softc, app, num_inputs); - bnxt_hwrm_queue_dscp2pri_qcfg(softc, app, num_inputs); + bnxt_hwrm_get_dcbx_app(softc, app, nitems, num_inputs); + bnxt_hwrm_queue_dscp2pri_qcfg(softc, app, nitems, num_inputs); return 0; } diff --git a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c index 72704c3db452..bbc12b96d8c6 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c @@ -139,6 +139,7 @@ bnxt_mgmt_process_dcb(struct cdev *dev, u_long cmd, caddr_t data, break; case BNXT_MGMT_DCB_LIST_APP: bnxt_dcb_ieee_listapp(softc, &mgmt_dcb.req.app_tlv.app[0], + nitems(mgmt_dcb.req.app_tlv.app), &mgmt_dcb.req.app_tlv.num_app); break; default: diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c index 012903ce21b3..45524aa1d076 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c @@ -1952,7 +1952,7 @@ bnxt_dcb_list_app(SYSCTL_HANDLER_ARGS) if (!buf) return ENOMEM; - bnxt_dcb_ieee_listapp(softc, app, &num_inputs); + bnxt_dcb_ieee_listapp(softc, app, nitems(app), &num_inputs); bnxt_app_tlv_get_string(softc, buf, app, num_inputs); rc = sysctl_handle_string(oidp, buf, BNXT_APP_TLV_STR_LEN, req);