Skip to content

Commit

Permalink
iwlwifi: fix double free/complete in firmware loading
Browse files Browse the repository at this point in the history
Linus reported that due to mac80211 failing to register
the device (due to WoWLAN) his machine crashed etc. as
we double-freed the vmalloc() firmware area. His patch
to fix it was very similar to this one but I noticed
that there's another bug in the area: we complete the
completion before starting, so since we're running in
a work struct context stop() could be called while in
the middle of start() which will almost certainly lead
to issues.

Make a modification similar to his to avoid the double-
free but also move the completion to another spot so it
is only done after start() either finished or failed so
that stop() can have a consistent state.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jun 5, 2012
1 parent fcb6ff5 commit f69a23b
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,13 +861,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)

/* We have our copies now, allow OS release its copies */
release_firmware(ucode_raw);
complete(&drv->request_firmware_complete);

drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);

if (!drv->op_mode)
goto out_free_fw;
goto out_unbind;

/*
* Complete the firmware request last so that
* a driver unbind (stop) doesn't run while we
* are doing the start() above.
*/
complete(&drv->request_firmware_complete);
return;

try_again:
Expand Down

0 comments on commit f69a23b

Please sign in to comment.