diff mbox series

[1/3] rtl8192cu: Fix deadlock

Message ID 20200622132113.14508-2-code@reto-schneider.ch
State New
Headers show
Series rtl8192cu: Fixes for leaks and deadlock | expand

Commit Message

Reto Schneider June 22, 2020, 1:21 p.m. UTC
Prevent code from calling itself indirectly, causing the driver to hang
and consume 100% CPU.

Without this fix, the following script can bring down a single CPU
system:
```
while true; do
  rmmod rtl8192cu
  modprobe rtl8192cu
done
```

Signed-off-by: Reto Schneider <code@reto-schneider.ch>
---
 drivers/net/wireless/realtek/rtlwifi/usb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Kalle Valo July 15, 2020, 10:37 a.m. UTC | #1
Reto Schneider <code@reto-schneider.ch> wrote:

> Prevent code from calling itself indirectly, causing the driver to hang

> and consume 100% CPU.

> 

> Without this fix, the following script can bring down a single CPU

> system:

> ```

> while true; do

>   rmmod rtl8192cu

>   modprobe rtl8192cu

> done

> ```

> 

> Signed-off-by: Reto Schneider <code@reto-schneider.ch>

> ACKed-by: Larry Finger <Larry.Finger@lwfinger.net>


3 patches applied to wireless-drivers-next.git, thanks.

ec89032cd148 rtlwifi: rtl8192cu: Fix deadlock
03128643eb54 rtlwifi: rtl8192cu: Prevent leaking urb
a7f7c15e945a rtlwifi: rtl8192cu: Free ieee80211_hw if probing fails

-- 
https://patchwork.kernel.org/patch/11617759/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
diff mbox series

Patch

diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c
index c66c6dc00378..d3bbfc0171f6 100644
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
@@ -680,8 +680,10 @@  static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
 	tasklet_kill(&rtlusb->rx_work_tasklet);
 	cancel_work_sync(&rtlpriv->works.lps_change_work);
 
-	flush_workqueue(rtlpriv->works.rtl_wq);
-	destroy_workqueue(rtlpriv->works.rtl_wq);
+	if (rtlpriv->works.rtl_wq) {
+		destroy_workqueue(rtlpriv->works.rtl_wq);
+		rtlpriv->works.rtl_wq = NULL;
+	}
 
 	skb_queue_purge(&rtlusb->rx_queue);