Skip to content

Commit 3d45a18

Browse files
jerome-pouillergregkh
authored andcommitted
staging: wfx: fix potential use before init
[ Upstream commit ce3653a ] The trace below can appear: [83613.832200] INFO: trying to register non-static key. [83613.837248] the code is fine but needs lockdep annotation. [83613.842808] turning off the locking correctness validator. [83613.848375] CPU: 3 PID: 141 Comm: kworker/3:2H Tainted: G O 5.6.13-silabs15 #2 [83613.857019] Hardware name: BCM2835 [83613.860605] Workqueue: events_highpri bh_work [wfx] [83613.865552] Backtrace: [83613.868041] [<c010f2cc>] (dump_backtrace) from [<c010f7b8>] (show_stack+0x20/0x24) [83613.881463] [<c010f798>] (show_stack) from [<c0d82138>] (dump_stack+0xe8/0x114) [83613.888882] [<c0d82050>] (dump_stack) from [<c01a02ec>] (register_lock_class+0x748/0x768) [83613.905035] [<c019fba4>] (register_lock_class) from [<c019da04>] (__lock_acquire+0x88/0x13dc) [83613.924192] [<c019d97c>] (__lock_acquire) from [<c019f6a4>] (lock_acquire+0xe8/0x274) [83613.942644] [<c019f5bc>] (lock_acquire) from [<c0daa5dc>] (_raw_spin_lock_irqsave+0x58/0x6c) [83613.961714] [<c0daa584>] (_raw_spin_lock_irqsave) from [<c0ab3248>] (skb_dequeue+0x24/0x78) [83613.974967] [<c0ab3224>] (skb_dequeue) from [<bf330db0>] (wfx_tx_queues_get+0x96c/0x1294 [wfx]) [83613.989728] [<bf330444>] (wfx_tx_queues_get [wfx]) from [<bf320454>] (bh_work+0x454/0x26d8 [wfx]) [83614.009337] [<bf320000>] (bh_work [wfx]) from [<c014c920>] (process_one_work+0x23c/0x7ec) [83614.028141] [<c014c6e4>] (process_one_work) from [<c014cf1c>] (worker_thread+0x4c/0x55c) [83614.046861] [<c014ced0>] (worker_thread) from [<c0154c04>] (kthread+0x138/0x168) [83614.064876] [<c0154acc>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20) [83614.072200] Exception stack(0xecad3fb0 to 0xecad3ff8) [83614.077323] 3fa0: 00000000 00000000 00000000 00000000 [83614.085620] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [83614.093914] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 Indeed, the code of wfx_add_interface() shows that the interface is enabled to early. So, the spinlock associated with some skb_queue may not yet initialized when wfx_tx_queues_get() is called. Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com> Link: https://lore.kernel.org/r/20200825085828.399505-8-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f25af2f commit 3d45a18

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

drivers/staging/wfx/sta.c

+14-14
Original file line numberDiff line numberDiff line change
@@ -761,17 +761,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
761761
return -EOPNOTSUPP;
762762
}
763763

764-
for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
765-
if (!wdev->vif[i]) {
766-
wdev->vif[i] = vif;
767-
wvif->id = i;
768-
break;
769-
}
770-
}
771-
if (i == ARRAY_SIZE(wdev->vif)) {
772-
mutex_unlock(&wdev->conf_mutex);
773-
return -EOPNOTSUPP;
774-
}
775764
// FIXME: prefer use of container_of() to get vif
776765
wvif->vif = vif;
777766
wvif->wdev = wdev;
@@ -788,12 +777,22 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
788777
init_completion(&wvif->scan_complete);
789778
INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
790779

791-
mutex_unlock(&wdev->conf_mutex);
780+
wfx_tx_queues_init(wvif);
781+
wfx_tx_policy_init(wvif);
782+
783+
for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
784+
if (!wdev->vif[i]) {
785+
wdev->vif[i] = vif;
786+
wvif->id = i;
787+
break;
788+
}
789+
}
790+
WARN(i == ARRAY_SIZE(wdev->vif), "try to instantiate more vif than supported");
792791

793792
hif_set_macaddr(wvif, vif->addr);
794793

795-
wfx_tx_queues_init(wvif);
796-
wfx_tx_policy_init(wvif);
794+
mutex_unlock(&wdev->conf_mutex);
795+
797796
wvif = NULL;
798797
while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
799798
// Combo mode does not support Block Acks. We can re-enable them
@@ -825,6 +824,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
825824
wvif->vif = NULL;
826825

827826
mutex_unlock(&wdev->conf_mutex);
827+
828828
wvif = NULL;
829829
while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
830830
// Combo mode does not support Block Acks. We can re-enable them

0 commit comments

Comments
 (0)