diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 26ba27e3992d..1f1a550828fa 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -221,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section, * without overflowing, so no check is needed. */ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, - u8 *data) + u8 *data, u32 size_read) { u16 length, offset = 0; int ret; @@ -233,6 +233,13 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, /* Read the NVM until exhausted (reading less than requested) */ while (ret == length) { + /* Check no memory assumptions fail and cause an overflow */ + if ((size_read + offset + length) > + mvm->cfg->base_params->eeprom_size) { + IWL_ERR(mvm, "EEPROM size is too small for NVM\n"); + return -ENOBUFS; + } + ret = iwl_nvm_read_chunk(mvm, section, offset, length, data); if (ret < 0) { IWL_DEBUG_EEPROM(mvm->trans->dev, @@ -470,6 +477,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm) int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) { int ret, section; + u32 size_read = 0; u8 *nvm_buffer, *temp; if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) @@ -486,9 +494,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) return -ENOMEM; for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) { /* we override the constness for initial read */ - ret = iwl_nvm_read_section(mvm, section, nvm_buffer); + ret = iwl_nvm_read_section(mvm, section, nvm_buffer, + size_read); if (ret < 0) continue; + size_read += ret; temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); if (!temp) { ret = -ENOMEM;