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.porsch@loopia.se>
Fixes:	35b53f8c989f bnxt_en: Add PFC, ETS & App TLVs protocols support
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D48589

(cherry picked from commit 3de231b4d956f7b9c22e31f75805030a417f7bf3)
This commit is contained in:
Zhenlei Huang 2025-02-14 18:38:29 +08:00 committed by Franco Fichtner
parent 52bb0884e6
commit 3b44f6fb78
4 changed files with 14 additions and 9 deletions

View File

@ -1309,6 +1309,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 */

View File

@ -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;
}

View File

@ -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:

View File

@ -1953,7 +1953,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);