[PATCH] ath9k: fix possible sleep-in-atomic-context bugs in hif_usb_send_regout()
From: Jia-Ju Bai <hidden>
Date: 2019-12-18 11:46:54
Also in:
linux-wireless, lkml
Subsystem:
atheros ath generic utilities, qualcomm atheros ath9k wireless driver, the rest · Maintainers:
Jeff Johnson, Toke Høiland-Jørgensen, Linus Torvalds
The driver may sleep while holding a spinlock. The function call path (from bottom to top) in Linux 4.19 is: drivers/net/wireless/ath/ath9k/hif_usb.c, 108: usb_alloc_urb(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/hif_usb.c, 112: kzalloc(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/hif_usb.c, 127: usb_submit_urb(GFP_KERNEL) in hif_usb_send_regout drivers/net/wireless/ath/ath9k/hif_usb.c, 470: hif_usb_send_regout in hif_usb_send drivers/net/wireless/ath/ath9k/htc_hst.c, 34: (FUNC_PTR)hif_usb_send in htc_issue_send drivers/net/wireless/ath/ath9k/htc_hst.c, 295: htc_issue_send in htc_send drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 250: htc_send in ath9k_htc_send_beacon drivers/net/wireless/ath/ath9k/htc_drv_beacon.c, 207: spin_lock_bh in ath9k_htc_send_beacon (FUNC_PTR) means a function pointer is called. To fix these bugs, GFP_KERNEL is replaced with GFP_ATOMIC. These bugs are found by a static analysis tool STCheck written by myself. Signed-off-by: Jia-Ju Bai <redacted> --- drivers/net/wireless/ath/ath9k/hif_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index fb649d85b8fc..37231fde102d 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c@@ -105,11 +105,11 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, struct cmd_buf *cmd; int ret = 0; - urb = usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, GFP_ATOMIC); if (urb == NULL) return -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); if (cmd == NULL) { usb_free_urb(urb); return -ENOMEM;
@@ -124,7 +124,7 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, hif_usb_regout_cb, cmd, 1); usb_anchor_urb(urb, &hif_dev->regout_submitted); - ret = usb_submit_urb(urb, GFP_KERNEL); + ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { usb_unanchor_urb(urb); kfree(cmd);
--
2.17.1