Bug#964480: linux: ath9k (USB) broken in upstresm linux 5.7.3 after commit 6602f080cb
Source: linux
Version: 5.7.0-1
Severity: normal
Tags: upstream patch
Dear Maintainer,
see https://bugzilla.kernel.org/show_bug.cgi?id=208251.
This affects all kernel versions that include
ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb
by
Qiujun Huang <hqjagain@gmail.com>
In 5.7 reverting 6602f080cb is known to fix the problem, but it hasn't yet been
analyzed by an expert, therefore I'd like to report my findings to perhaps get
an expert interested:-)
At least one problem is in function ath9k_hif_usb_reg_in_cb(). In the call to
usb_fill_int_urb() it should be rx_buf instead of nskb as penultimate
parameter.
I'm currently running the following patch to send this bug report using my ath9k
dongle.
Best regards
Jürgen
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 4ed21dad6a8e..f3622d686002 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -693,15 +693,8 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
struct hif_device_usb *hif_dev = rx_buf->hif_dev;
struct sk_buff *skb = rx_buf->skb;
- struct sk_buff *nskb;
int ret;
- if (!skb)
- return;
-
- if (!hif_dev)
- goto free;
-
switch (urb->status) {
case 0:
break;
@@ -711,9 +704,6 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
case -ESHUTDOWN:
goto free;
default:
- skb_reset_tail_pointer(skb);
- skb_trim(skb, 0);
-
goto resubmit;
}
@@ -725,22 +715,27 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
skb->len, USB_REG_IN_PIPE);
- nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
- if (!nskb) {
+ skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
+ if (!skb) {
dev_err(&hif_dev->udev->dev,
"ath9k_htc: REG_IN memory allocation failure\n");
urb->context = NULL;
- return;
+ goto free;
}
+ rx_buf->skb = skb;
+
usb_fill_int_urb(urb, hif_dev->udev,
usb_rcvintpipe(hif_dev->udev,
USB_REG_IN_PIPE),
- nskb->data, MAX_REG_IN_BUF_SIZE,
- ath9k_hif_usb_reg_in_cb, nskb, 1);
+ skb->data, MAX_REG_IN_BUF_SIZE,
+ ath9k_hif_usb_reg_in_cb, rx_buf, 1);
}
resubmit:
+ skb_reset_tail_pointer(skb);
+ skb_trim(skb, 0);
+
usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret) {
-- System Information:
Debian Release: bullseye/sid
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 5.7.0-1-686-pae (SMP w/8 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Reply to: