From 6b231fec923a354e6f75e8c924350cec3ddc46c3 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Fri, 30 Nov 2018 07:05:12 +0000 Subject: [PATCH] sfxge(4): avoid usage of too big arrays on stack Found by PreFAST static analysis. Submitted by: Martin Harvey Sponsored by: Solarflare Communications, Inc. MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D18257 --- sys/dev/sfxge/common/ef10_phy.c | 18 +++++++++++++++--- sys/dev/sfxge/common/efx_nvram.c | 27 ++++++++++++++++++--------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/sys/dev/sfxge/common/ef10_phy.c b/sys/dev/sfxge/common/ef10_phy.c index 999173e5baf5..db00910871da 100644 --- a/sys/dev/sfxge/common/ef10_phy.c +++ b/sys/dev/sfxge/common/ef10_phy.c @@ -610,14 +610,26 @@ ef10_bist_poll( unsigned long *valuesp, __in size_t count) { + /* + * MCDI_CTL_SDU_LEN_MAX_V1 is large enough cover all BIST results, + * whilst not wasting stack. + */ + uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, MCDI_CTL_SDU_LEN_MAX_V1)]; efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_mcdi_req_t req; - uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN, - MCDI_CTL_SDU_LEN_MAX)]; uint32_t value_mask = 0; uint32_t result; efx_rc_t rc; + EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_LEN <= + MCDI_CTL_SDU_LEN_MAX_V1); + EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_SFT9001_LEN <= + MCDI_CTL_SDU_LEN_MAX_V1); + EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MRSFP_LEN <= + MCDI_CTL_SDU_LEN_MAX_V1); + EFX_STATIC_ASSERT(MC_CMD_POLL_BIST_OUT_MEM_LEN <= + MCDI_CTL_SDU_LEN_MAX_V1); + _NOTE(ARGUNUSED(type)) (void) memset(payload, 0, sizeof (payload)); @@ -625,7 +637,7 @@ ef10_bist_poll( req.emr_in_buf = payload; req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN; req.emr_out_buf = payload; - req.emr_out_length = MCDI_CTL_SDU_LEN_MAX; + req.emr_out_length = MCDI_CTL_SDU_LEN_MAX_V1; efx_mcdi_execute(enp, &req); diff --git a/sys/dev/sfxge/common/efx_nvram.c b/sys/dev/sfxge/common/efx_nvram.c index b18ed4a91104..08ff3f02cb7c 100644 --- a/sys/dev/sfxge/common/efx_nvram.c +++ b/sys/dev/sfxge/common/efx_nvram.c @@ -898,23 +898,27 @@ efx_mcdi_nvram_write( __in size_t size) { efx_mcdi_req_t req; - uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1, - MCDI_CTL_SDU_LEN_MAX_V2)]; + uint8_t *payload; efx_rc_t rc; size_t max_data_size; + size_t payload_len = enp->en_nic_cfg.enc_mcdi_max_payload_length; - max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length - - MC_CMD_NVRAM_WRITE_IN_LEN(0); - EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0); - EFSYS_ASSERT3U(max_data_size, <, - enp->en_nic_cfg.enc_mcdi_max_payload_length); + max_data_size = payload_len - MC_CMD_NVRAM_WRITE_IN_LEN(0); + EFSYS_ASSERT3U(payload_len, >, 0); + EFSYS_ASSERT3U(max_data_size, <, payload_len); if (size > max_data_size) { rc = EINVAL; goto fail1; } - (void) memset(payload, 0, sizeof (payload)); + EFSYS_KMEM_ALLOC(enp->en_esip, payload_len, payload); + if (payload == NULL) { + rc = ENOMEM; + goto fail2; + } + + (void) memset(payload, 0, payload_len); req.emr_cmd = MC_CMD_NVRAM_WRITE; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size); @@ -932,11 +936,16 @@ efx_mcdi_nvram_write( if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail2; + goto fail3; } + EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload); + return (0); +fail3: + EFSYS_PROBE(fail3); + EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload); fail2: EFSYS_PROBE(fail2); fail1: