Skip to content

Commit

Permalink
iwlwifi: fix leaks/bad data after failed firmware load
Browse files Browse the repository at this point in the history
If firmware load fails after having loaded some parts of the
firmware, e.g. the IML image, then this would leak. For the
host command list we'd end up running into a WARN on the next
attempt to load another firmware image.

Fix this by calling iwl_dealloc_ucode() on failures, and make
that also clear the data so we start fresh on the next round.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20211210110539.1f742f0eb58a.I1315f22f6aa632d94ae2069f85e1bca5e734dce0@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
  • Loading branch information
jmberg-intel authored and lucacoelho committed Dec 21, 2021
1 parent ccbffd6 commit ab07506
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/iwl-drv.c
Expand Up @@ -130,6 +130,9 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)

for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);

/* clear the data for the aborted load case */
memset(&drv->fw, 0, sizeof(drv->fw));
}

static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
Expand Down Expand Up @@ -1426,6 +1429,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
int i;
bool load_module = false;
bool usniffer_images = false;
bool failure = true;

fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
fw->ucode_capa.standard_phy_calibration_size =
Expand Down Expand Up @@ -1695,6 +1699,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
op->name, err);
#endif
}
failure = false;
goto free;

try_again:
Expand All @@ -1710,6 +1715,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
complete(&drv->request_firmware_complete);
device_release_driver(drv->trans->dev);
free:
if (failure)
iwl_dealloc_ucode(drv);

if (pieces) {
for (i = 0; i < ARRAY_SIZE(pieces->img); i++)
kfree(pieces->img[i].sec);
Expand Down

0 comments on commit ab07506

Please sign in to comment.