[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: