Return-path: Received: from mga03.intel.com ([143.182.124.21]:4744 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752343Ab3J3UcM (ORCPT ); Wed, 30 Oct 2013 16:32:12 -0400 From: Emmanuel Grumbach To: John Linville Cc: linux-wireless@vger.kernel.org, Emmanuel Grumbach Subject: [PATCH 3/9] iwlwifi: mvm: BT Coex fix NULL pointer dereference Date: Wed, 30 Oct 2013 22:31:31 +0200 Message-Id: <1383165097-4445-3-git-send-email-emmanuel.grumbach@intel.com> (sfid-20131030_213218_447737_FBF8FF02) In-Reply-To: <1383165097-4445-1-git-send-email-emmanuel.grumbach@intel.com> References: <527143AA.5070900@gmail.com> <1383165097-4445-1-git-send-email-emmanuel.grumbach@intel.com> Sender: linux-wireless-owner@vger.kernel.org List-ID: When we disassociate, mac80211 removes the station and then, it sets the bss it unsets the assoc bool in bss_info. Since the firwmware wants it the opposite (first set the MAC context as unassoc, and only then, remove the STA of the API), we have a small period of time in which the STA in firmware doesn't have a valid ieee80211_sta pointer. During that time, iwl_mvm_vif->ap_sta_id, is still set to the STA in firmware that represent the AP. This avoids: [ 4481.476246] BUG: unable to handle kernel NULL pointer dereference at 00000045 [ 4481.479521] IP: [] iwl_mvm_bt_coex_reduced_txp+0x7a/0x190 [iwlmvm] [ 4481.482023] *pde = 00000000 [ 4481.484332] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC [ 4481.486897] Modules linked in: netconsole configfs autofs4 rfcomm(O) bnep(O) nfsd nfs_acl auth_rpcgss exportfs nfs lockd binfmt_misc sunrpc fscache arc4 iwlmvm(O) mac80211(O) btusb(O) iwlwifi(O) bluetooth(O) cfg80211(O) snd_hda_codec_hdmi coretemp dell_wmi snd_hda_codec_idt compat(O) dell_laptop aesni_intel i915 sparse_keymap dcdbas cryptd psmouse serio_raw aes_i586 microcode snd_hda_intel drm_kms_helper snd_hda_codec drm snd_pcm snd_timer i2c_algo_bit video intel_agp intel_gtt snd soundcore snd_page_alloc crc32c_intel ahci sdhci_pci libahci sdhci mmc_core e1000e xhci_hcd [last unloaded: configfs] [ 4481.502983] [ 4481.505599] Pid: 6507, comm: kworker/0:1 Tainted: G O 3.4.43-dev #1 Dell Inc. Latitude E6430/0CMDYV [ 4481.508575] EIP: 0060:[] EFLAGS: 00010246 CPU: 0 [ 4481.511248] EIP is at iwl_mvm_bt_coex_reduced_txp+0x7a/0x190 [iwlmvm] [ 4481.513947] EAX: ffffffea EBX: 00000002 ECX: 00000001 EDX: 00000001 [ 4481.516710] ESI: ec6f0f28 EDI: 00000000 EBP: e8175dfc ESP: e8175d9c [ 4481.519445] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 4481.522185] CR0: 8005003b CR2: 00000045 CR3: 01a5e000 CR4: 001407d0 [ 4481.524950] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [ 4481.527768] DR6: ffff0ff0 DR7: 00000400 [ 4481.530565] Process kworker/0:1 (pid: 6507, ti=e8174000 task=e8032b20 task.ti=e8174000) [ 4481.533447] Stack: [ 4481.536379] e472439f 00003a12 e8032b20 e8033048 00000001 e8175ddc 00000246 e8033040 [ 4481.540132] 00000002 01814990 ec4d1ddc e8175dcc 00000000 00000000 00000000 00000000 [ 4481.543867] 00000000 00000000 00000001 000001c8 009b0002 ec4d1ddc ec6f0f28 00000000 [ 4481.547633] Call Trace: [ 4481.550578] [] iwl_mvm_bt_rssi_event+0x197/0x220 [iwlmvm] [ 4481.553537] [] iwl_mvm_stat_iterator+0xdc/0x240 [iwlmvm] [ 4481.556582] [] __iterate_active_interfaces+0xe2/0x1f0 [mac80211] [ 4481.559544] [] ? iwl_mvm_update_smps+0x90/0x90 [iwlmvm] [ 4481.562519] [] ? iwl_mvm_update_smps+0x90/0x90 [iwlmvm] [ 4481.565498] [] ieee80211_iterate_active_interfaces+0x3c/0x50 [mac80211] [ 4481.568421] [] iwl_mvm_rx_statistics+0xb3/0x130 [iwlmvm] [ 4481.571349] [] iwl_mvm_async_handlers_wk+0xc1/0xf0 [iwlmvm] [ 4481.574251] [] ? process_one_work+0x105/0x5c0 [ 4481.577162] [] process_one_work+0x181/0x5c0 [ 4481.580025] [] ? process_one_work+0x105/0x5c0 [ 4481.582861] [] ? iwl_mvm_rx_fw_logs+0x20/0x20 [iwlmvm] [ 4481.585722] [] worker_thread+0x121/0x2c0 [ 4481.588536] [] ? rescuer_thread+0x1d0/0x1d0 [ 4481.591323] [] kthread+0x7d/0x90 [ 4481.594059] [] ? flush_kthread_worker+0x120/0x120 [ 4481.596868] [] kernel_thread_helper+0x6/0x10 [ 4481.599605] Code: 9d de c3 c8 85 c0 74 0d 80 3d f8 ae 42 f8 00 0f 84 dc 00 00 00 8b 45 c8 0f b6 d3 31 ff 89 55 c0 8b 84 90 d8 03 00 00 0f b6 55 c7 <38> 50 5b 89 45 bc 0f 84 a8 00 00 00 a1 e4 d2 04 c2 85 c0 0f 84 [ 4481.611782] EIP: [] iwl_mvm_bt_coex_reduced_txp+0x7a/0x190 [iwlmvm] SS:ESP 0068:e8175d9c [ 4481.614985] CR2: 0000000000000045 [ 4481.687441] ---[ end trace b11bc915fbac4412 ]--- Reviewed-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 5b630f12b..7444b2a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -505,12 +505,16 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, struct iwl_mvm_sta *mvmsta; int ret; - /* This can happen if the station has been removed right now */ if (sta_id == IWL_MVM_STATION_COUNT) return 0; sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], lockdep_is_held(&mvm->mutex)); + + /* This can happen if the station has been removed right now */ + if (IS_ERR_OR_NULL(sta)) + return 0; + mvmsta = (void *)sta->drv_priv; /* nothing to do */ -- 1.8.3.2