From e27950a02b035a6d366ed362c6719b6c892dda6b Mon Sep 17 00:00:00 2001 From: Andy Moreton Date: Tue, 18 May 2021 18:10:12 +0300 Subject: [PATCH] common/sfc_efx/base: add missing MCDI response length checks Fixes: 6f619653b9b1 ("net/sfc/base: import MCDI implementation") Fixes: e7cd430c864f ("net/sfc/base: import SFN7xxx family support") Fixes: 94190e3543bf ("net/sfc/base: import SFN8xxx family support") Fixes: 34285fd0891d ("common/sfc_efx/base: add match spec validate API") Fixes: e61baa82e64b ("common/sfc_efx/base: add MAE action set provisioning APIs") Fixes: b4fac34715f2 ("common/sfc_efx/base: add MAE action rule provisioning APIs") Fixes: ed15d7f8e064 ("common/sfc_efx/base: validate and compare outer match specs") Fixes: 7a673e1a4a05 ("common/sfc_efx/base: support outer rule provisioning") Cc: stable@dpdk.org Signed-off-by: Andy Moreton Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko --- drivers/common/sfc_efx/base/ef10_filter.c | 11 ++++- drivers/common/sfc_efx/base/ef10_nic.c | 10 ++++- drivers/common/sfc_efx/base/efx_mae.c | 52 +++++++++++++++++++---- drivers/common/sfc_efx/base/efx_mcdi.c | 7 +++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_filter.c b/drivers/common/sfc_efx/base/ef10_filter.c index 0c99d4b74b..ac6006c9b4 100644 --- a/drivers/common/sfc_efx/base/ef10_filter.c +++ b/drivers/common/sfc_efx/base/ef10_filter.c @@ -1225,20 +1225,25 @@ efx_mcdi_get_parser_disp_info( goto fail1; } + if (req.emr_out_length_used < MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail2; + } + matches_count = MCDI_OUT_DWORD(req, GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES); if (req.emr_out_length_used < MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(matches_count)) { rc = EMSGSIZE; - goto fail2; + goto fail3; } *list_lengthp = matches_count; if (buffer_length < matches_count) { rc = ENOSPC; - goto fail3; + goto fail4; } /* @@ -1258,6 +1263,8 @@ efx_mcdi_get_parser_disp_info( return (0); +fail4: + EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); fail2: diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index 531365e420..eda0ad3068 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -491,11 +491,17 @@ efx_mcdi_get_rxdp_config( req.emr_out_length = MC_CMD_GET_RXDP_CONFIG_OUT_LEN; efx_mcdi_execute(enp, &req); + if (req.emr_rc != 0) { rc = req.emr_rc; goto fail1; } + if (req.emr_out_length_used < MC_CMD_GET_RXDP_CONFIG_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + if (MCDI_OUT_DWORD_FIELD(req, GET_RXDP_CONFIG_OUT_DATA, GET_RXDP_CONFIG_OUT_PAD_HOST_DMA) == 0) { /* RX DMA end padding is disabled */ @@ -514,7 +520,7 @@ efx_mcdi_get_rxdp_config( break; default: rc = ENOTSUP; - goto fail2; + goto fail3; } } @@ -522,6 +528,8 @@ efx_mcdi_get_rxdp_config( return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 80fe155d0d..c1784211e7 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -109,17 +109,22 @@ efx_mae_get_outer_rule_caps( goto fail2; } + if (req.emr_out_length_used < MC_CMD_MAE_GET_OR_CAPS_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + mcdi_field_ncaps = MCDI_OUT_DWORD(req, MAE_GET_OR_CAPS_OUT_COUNT); if (req.emr_out_length_used < MC_CMD_MAE_GET_OR_CAPS_OUT_LEN(mcdi_field_ncaps)) { rc = EMSGSIZE; - goto fail3; + goto fail4; } if (mcdi_field_ncaps > field_ncaps) { rc = EMSGSIZE; - goto fail4; + goto fail5; } for (i = 0; i < mcdi_field_ncaps; ++i) { @@ -147,6 +152,8 @@ efx_mae_get_outer_rule_caps( return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -191,17 +198,22 @@ efx_mae_get_action_rule_caps( goto fail2; } - mcdi_field_ncaps = MCDI_OUT_DWORD(req, MAE_GET_OR_CAPS_OUT_COUNT); + if (req.emr_out_length_used < MC_CMD_MAE_GET_AR_CAPS_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + + mcdi_field_ncaps = MCDI_OUT_DWORD(req, MAE_GET_AR_CAPS_OUT_COUNT); if (req.emr_out_length_used < MC_CMD_MAE_GET_AR_CAPS_OUT_LEN(mcdi_field_ncaps)) { rc = EMSGSIZE; - goto fail3; + goto fail4; } if (mcdi_field_ncaps > field_ncaps) { rc = EMSGSIZE; - goto fail4; + goto fail5; } for (i = 0; i < mcdi_field_ncaps; ++i) { @@ -229,6 +241,8 @@ efx_mae_get_action_rule_caps( return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -1773,15 +1787,22 @@ efx_mae_outer_rule_remove( goto fail2; } + if (req.emr_out_length_used < MC_CMD_MAE_OUTER_RULE_REMOVE_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + if (MCDI_OUT_DWORD(req, MAE_OUTER_RULE_REMOVE_OUT_REMOVED_OR_ID) != or_idp->id) { /* Firmware failed to remove the outer rule. */ rc = EAGAIN; - goto fail3; + goto fail4; } return (0); +fail4: + EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); fail2: @@ -2176,15 +2197,22 @@ efx_mae_action_set_free( goto fail2; } + if (req.emr_out_length_used < MC_CMD_MAE_ACTION_SET_FREE_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + if (MCDI_OUT_DWORD(req, MAE_ACTION_SET_FREE_OUT_FREED_AS_ID) != aset_idp->id) { /* Firmware failed to free the action set. */ rc = EAGAIN; - goto fail3; + goto fail4; } return (0); +fail4: + EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); fail2: @@ -2326,15 +2354,23 @@ efx_mae_action_rule_remove( goto fail2; } + if (req.emr_out_length_used < + MC_CMD_MAE_ACTION_RULE_DELETE_OUT_LENMIN) { + rc = EMSGSIZE; + goto fail3; + } + if (MCDI_OUT_DWORD(req, MAE_ACTION_RULE_DELETE_OUT_DELETED_AR_ID) != ar_idp->id) { /* Firmware failed to delete the action rule. */ rc = EAGAIN; - goto fail3; + goto fail4; } return (0); +fail4: + EFSYS_PROBE(fail4); fail3: EFSYS_PROBE(fail3); fail2: diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index f4e1384d09..f226ffd923 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -2294,6 +2294,11 @@ efx_mcdi_get_workarounds( goto fail1; } + if (req.emr_out_length_used < MC_CMD_GET_WORKAROUNDS_OUT_LEN) { + rc = EMSGSIZE; + goto fail2; + } + if (implementedp != NULL) { *implementedp = MCDI_OUT_DWORD(req, GET_WORKAROUNDS_OUT_IMPLEMENTED); @@ -2305,6 +2310,8 @@ efx_mcdi_get_workarounds( return (0); +fail2: + EFSYS_PROBE(fail2); fail1: EFSYS_PROBE1(fail1, efx_rc_t, rc); -- 2.20.1