]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2019 09:47:38 +0000 (10:47 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2019 09:47:38 +0000 (10:47 +0100)
added patches:
ath10k-fix-a-null-ptr-deref-bug-in-ath10k_usb_alloc_urb_from_pipe.patch
ath10k-fix-host-capability-qmi-incompatibility.patch
ath10k-restore-qca9880-ar1a-v1-detection.patch
ath9k_hw-fix-uninitialized-variable-data.patch

queue-5.3/ath10k-fix-a-null-ptr-deref-bug-in-ath10k_usb_alloc_urb_from_pipe.patch [new file with mode: 0644]
queue-5.3/ath10k-fix-host-capability-qmi-incompatibility.patch [new file with mode: 0644]
queue-5.3/ath10k-restore-qca9880-ar1a-v1-detection.patch [new file with mode: 0644]
queue-5.3/ath9k_hw-fix-uninitialized-variable-data.patch [new file with mode: 0644]
queue-5.3/series

diff --git a/queue-5.3/ath10k-fix-a-null-ptr-deref-bug-in-ath10k_usb_alloc_urb_from_pipe.patch b/queue-5.3/ath10k-fix-a-null-ptr-deref-bug-in-ath10k_usb_alloc_urb_from_pipe.patch
new file mode 100644 (file)
index 0000000..eb1a040
--- /dev/null
@@ -0,0 +1,74 @@
+From bfd6e6e6c5d2ee43a3d9902b36e01fc7527ebb27 Mon Sep 17 00:00:00 2001
+From: Hui Peng <benquike@gmail.com>
+Date: Sat, 19 Oct 2019 14:42:23 +0300
+Subject: ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
+
+From: Hui Peng <benquike@gmail.com>
+
+commit bfd6e6e6c5d2ee43a3d9902b36e01fc7527ebb27 upstream.
+
+The `ar_usb` field of `ath10k_usb_pipe_usb_pipe` objects
+are initialized to point to the containing `ath10k_usb` object
+according to endpoint descriptors read from the device side, as shown
+below in `ath10k_usb_setup_pipe_resources`:
+
+for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+        endpoint = &iface_desc->endpoint[i].desc;
+
+        // get the address from endpoint descriptor
+        pipe_num = ath10k_usb_get_logical_pipe_num(ar_usb,
+                                                endpoint->bEndpointAddress,
+                                                &urbcount);
+        ......
+        // select the pipe object
+        pipe = &ar_usb->pipes[pipe_num];
+
+        // initialize the ar_usb field
+        pipe->ar_usb = ar_usb;
+}
+
+The driver assumes that the addresses reported in endpoint
+descriptors from device side  to be complete. If a device is
+malicious and does not report complete addresses, it may trigger
+NULL-ptr-deref `ath10k_usb_alloc_urb_from_pipe` and
+`ath10k_usb_free_urb_to_pipe`.
+
+This patch fixes the bug by preventing potential NULL-ptr-deref.
+
+Signed-off-by: Hui Peng <benquike@gmail.com>
+Reported-by: Hui Peng <benquike@gmail.com>
+Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[groeck: Add driver tag to subject, fix build warning]
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/usb.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath10k/usb.c
++++ b/drivers/net/wireless/ath/ath10k/usb.c
+@@ -38,6 +38,10 @@ ath10k_usb_alloc_urb_from_pipe(struct at
+       struct ath10k_urb_context *urb_context = NULL;
+       unsigned long flags;
++      /* bail if this pipe is not initialized */
++      if (!pipe->ar_usb)
++              return NULL;
++
+       spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
+       if (!list_empty(&pipe->urb_list_head)) {
+               urb_context = list_first_entry(&pipe->urb_list_head,
+@@ -55,6 +59,10 @@ static void ath10k_usb_free_urb_to_pipe(
+ {
+       unsigned long flags;
++      /* bail if this pipe is not initialized */
++      if (!pipe->ar_usb)
++              return;
++
+       spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
+       pipe->urb_cnt++;
diff --git a/queue-5.3/ath10k-fix-host-capability-qmi-incompatibility.patch b/queue-5.3/ath10k-fix-host-capability-qmi-incompatibility.patch
new file mode 100644 (file)
index 0000000..dfe50bb
--- /dev/null
@@ -0,0 +1,168 @@
+From 7165ef890a4c44cf16db66b82fd78448f4bde6ba Mon Sep 17 00:00:00 2001
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+Date: Wed, 24 Jul 2019 23:31:08 -0700
+Subject: ath10k: Fix HOST capability QMI incompatibility
+
+From: Bjorn Andersson <bjorn.andersson@linaro.org>
+
+commit 7165ef890a4c44cf16db66b82fd78448f4bde6ba upstream.
+
+The introduction of 768ec4c012ac ("ath10k: update HOST capability QMI
+message") served the purpose of supporting the new and extended HOST
+capability QMI message.
+
+But while the new message adds a slew of optional members it changes the
+data type of the "daemon_support" member, which means that older
+versions of the firmware will fail to decode the incoming request
+message.
+
+There is no way to detect this breakage from Linux and there's no way to
+recover from sending the wrong message (i.e. we can't just try one
+format and then fallback to the other), so a quirk is introduced in
+DeviceTree to indicate to the driver that the firmware requires the 8bit
+version of this message.
+
+Cc: stable@vger.kernel.org
+Fixes: 768ec4c012ac ("ath10k: update HOST capability qmi message")
+Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt |    6 ++
+ drivers/net/wireless/ath/ath10k/qmi.c                          |   13 ++++-
+ drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c                 |   22 ++++++++++
+ drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h                 |    1 
+ drivers/net/wireless/ath/ath10k/snoc.c                         |   11 +++++
+ drivers/net/wireless/ath/ath10k/snoc.h                         |    1 
+ 6 files changed, 51 insertions(+), 3 deletions(-)
+
+--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
++++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+@@ -81,6 +81,12 @@ Optional properties:
+       Definition: Name of external front end module used. Some valid FEM names
+                   for example: "microsemi-lx5586", "sky85703-11"
+                   and "sky85803" etc.
++- qcom,snoc-host-cap-8bit-quirk:
++      Usage: Optional
++      Value type: <empty>
++      Definition: Quirk specifying that the firmware expects the 8bit version
++                  of the host capability QMI request
++
+ Example (to supply PCI based wifi block details):
+--- a/drivers/net/wireless/ath/ath10k/qmi.c
++++ b/drivers/net/wireless/ath/ath10k/qmi.c
+@@ -581,22 +581,29 @@ static int ath10k_qmi_host_cap_send_sync
+ {
+       struct wlfw_host_cap_resp_msg_v01 resp = {};
+       struct wlfw_host_cap_req_msg_v01 req = {};
++      struct qmi_elem_info *req_ei;
+       struct ath10k *ar = qmi->ar;
++      struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+       struct qmi_txn txn;
+       int ret;
+       req.daemon_support_valid = 1;
+       req.daemon_support = 0;
+-      ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
+-                         wlfw_host_cap_resp_msg_v01_ei, &resp);
++      ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_host_cap_resp_msg_v01_ei,
++                         &resp);
+       if (ret < 0)
+               goto out;
++      if (test_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags))
++              req_ei = wlfw_host_cap_8bit_req_msg_v01_ei;
++      else
++              req_ei = wlfw_host_cap_req_msg_v01_ei;
++
+       ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
+                              QMI_WLFW_HOST_CAP_REQ_V01,
+                              WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN,
+-                             wlfw_host_cap_req_msg_v01_ei, &req);
++                             req_ei, &req);
+       if (ret < 0) {
+               qmi_txn_cancel(&txn);
+               ath10k_err(ar, "failed to send host capability request: %d\n", ret);
+--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c
+@@ -1988,6 +1988,28 @@ struct qmi_elem_info wlfw_host_cap_req_m
+       {}
+ };
++struct qmi_elem_info wlfw_host_cap_8bit_req_msg_v01_ei[] = {
++      {
++              .data_type      = QMI_OPT_FLAG,
++              .elem_len       = 1,
++              .elem_size      = sizeof(u8),
++              .array_type     = NO_ARRAY,
++              .tlv_type       = 0x10,
++              .offset         = offsetof(struct wlfw_host_cap_req_msg_v01,
++                                         daemon_support_valid),
++      },
++      {
++              .data_type      = QMI_UNSIGNED_1_BYTE,
++              .elem_len       = 1,
++              .elem_size      = sizeof(u8),
++              .array_type     = NO_ARRAY,
++              .tlv_type       = 0x10,
++              .offset         = offsetof(struct wlfw_host_cap_req_msg_v01,
++                                         daemon_support),
++      },
++      {}
++};
++
+ struct qmi_elem_info wlfw_host_cap_resp_msg_v01_ei[] = {
+       {
+               .data_type      = QMI_STRUCT,
+--- a/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
++++ b/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h
+@@ -575,6 +575,7 @@ struct wlfw_host_cap_req_msg_v01 {
+ #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 189
+ extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[];
++extern struct qmi_elem_info wlfw_host_cap_8bit_req_msg_v01_ei[];
+ struct wlfw_host_cap_resp_msg_v01 {
+       struct qmi_response_type_v01 resp;
+--- a/drivers/net/wireless/ath/ath10k/snoc.c
++++ b/drivers/net/wireless/ath/ath10k/snoc.c
+@@ -1261,6 +1261,15 @@ out:
+       return ret;
+ }
++static void ath10k_snoc_quirks_init(struct ath10k *ar)
++{
++      struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
++      struct device *dev = &ar_snoc->dev->dev;
++
++      if (of_property_read_bool(dev->of_node, "qcom,snoc-host-cap-8bit-quirk"))
++              set_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags);
++}
++
+ int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type)
+ {
+       struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+@@ -1678,6 +1687,8 @@ static int ath10k_snoc_probe(struct plat
+       ar->ce_priv = &ar_snoc->ce;
+       msa_size = drv_data->msa_size;
++      ath10k_snoc_quirks_init(ar);
++
+       ret = ath10k_snoc_resource_init(ar);
+       if (ret) {
+               ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
+--- a/drivers/net/wireless/ath/ath10k/snoc.h
++++ b/drivers/net/wireless/ath/ath10k/snoc.h
+@@ -63,6 +63,7 @@ enum ath10k_snoc_flags {
+       ATH10K_SNOC_FLAG_REGISTERED,
+       ATH10K_SNOC_FLAG_UNREGISTERING,
+       ATH10K_SNOC_FLAG_RECOVERY,
++      ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK,
+ };
+ struct ath10k_snoc {
diff --git a/queue-5.3/ath10k-restore-qca9880-ar1a-v1-detection.patch b/queue-5.3/ath10k-restore-qca9880-ar1a-v1-detection.patch
new file mode 100644 (file)
index 0000000..40f9cc5
--- /dev/null
@@ -0,0 +1,101 @@
+From f8914a14623a79b73f72b2b1ee4cd9b2cb91b735 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Fri, 6 Sep 2019 23:54:23 +0200
+Subject: ath10k: restore QCA9880-AR1A (v1) detection
+
+From: Christian Lamparter <chunkeey@gmail.com>
+
+commit f8914a14623a79b73f72b2b1ee4cd9b2cb91b735 upstream.
+
+This patch restores the old behavior that read
+the chip_id on the QCA988x before resetting the
+chip. This needs to be done in this order since
+the unsupported QCA988x AR1A chips fall off the
+bus when resetted. Otherwise the next MMIO Op
+after the reset causes a BUS ERROR and panic.
+
+Cc: stable@vger.kernel.org
+Fixes: 1a7fecb766c8 ("ath10k: reset chip before reading chip_id in probe")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath10k/pci.c |   36 +++++++++++++++++++++++-----------
+ 1 file changed, 25 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3490,7 +3490,7 @@ static int ath10k_pci_probe(struct pci_d
+       struct ath10k_pci *ar_pci;
+       enum ath10k_hw_rev hw_rev;
+       struct ath10k_bus_params bus_params = {};
+-      bool pci_ps;
++      bool pci_ps, is_qca988x = false;
+       int (*pci_soft_reset)(struct ath10k *ar);
+       int (*pci_hard_reset)(struct ath10k *ar);
+       u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
+@@ -3500,6 +3500,7 @@ static int ath10k_pci_probe(struct pci_d
+       case QCA988X_2_0_DEVICE_ID:
+               hw_rev = ATH10K_HW_QCA988X;
+               pci_ps = false;
++              is_qca988x = true;
+               pci_soft_reset = ath10k_pci_warm_reset;
+               pci_hard_reset = ath10k_pci_qca988x_chip_reset;
+               targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr;
+@@ -3619,25 +3620,34 @@ static int ath10k_pci_probe(struct pci_d
+               goto err_deinit_irq;
+       }
++      bus_params.dev_type = ATH10K_DEV_TYPE_LL;
++      bus_params.link_can_suspend = true;
++      /* Read CHIP_ID before reset to catch QCA9880-AR1A v1 devices that
++       * fall off the bus during chip_reset. These chips have the same pci
++       * device id as the QCA9880 BR4A or 2R4E. So that's why the check.
++       */
++      if (is_qca988x) {
++              bus_params.chip_id =
++                      ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
++              if (bus_params.chip_id != 0xffffffff) {
++                      if (!ath10k_pci_chip_is_supported(pdev->device,
++                                                        bus_params.chip_id))
++                              goto err_unsupported;
++              }
++      }
++
+       ret = ath10k_pci_chip_reset(ar);
+       if (ret) {
+               ath10k_err(ar, "failed to reset chip: %d\n", ret);
+               goto err_free_irq;
+       }
+-      bus_params.dev_type = ATH10K_DEV_TYPE_LL;
+-      bus_params.link_can_suspend = true;
+       bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
+-      if (bus_params.chip_id == 0xffffffff) {
+-              ath10k_err(ar, "failed to get chip id\n");
+-              goto err_free_irq;
+-      }
++      if (bus_params.chip_id == 0xffffffff)
++              goto err_unsupported;
+-      if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) {
+-              ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
+-                         pdev->device, bus_params.chip_id);
++      if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id))
+               goto err_free_irq;
+-      }
+       ret = ath10k_core_register(ar, &bus_params);
+       if (ret) {
+@@ -3647,6 +3657,10 @@ static int ath10k_pci_probe(struct pci_d
+       return 0;
++err_unsupported:
++      ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
++                 pdev->device, bus_params.chip_id);
++
+ err_free_irq:
+       ath10k_pci_free_irq(ar);
+       ath10k_pci_rx_retry_sync(ar);
diff --git a/queue-5.3/ath9k_hw-fix-uninitialized-variable-data.patch b/queue-5.3/ath9k_hw-fix-uninitialized-variable-data.patch
new file mode 100644 (file)
index 0000000..b81cadc
--- /dev/null
@@ -0,0 +1,39 @@
+From 80e84f36412e0c5172447b6947068dca0d04ee82 Mon Sep 17 00:00:00 2001
+From: Denis Efremov <efremov@linux.com>
+Date: Fri, 27 Sep 2019 01:56:04 +0300
+Subject: ath9k_hw: fix uninitialized variable data
+
+From: Denis Efremov <efremov@linux.com>
+
+commit 80e84f36412e0c5172447b6947068dca0d04ee82 upstream.
+
+Currently, data variable in ar9003_hw_thermo_cal_apply() could be
+uninitialized if ar9300_otp_read_word() will fail to read the value.
+Initialize data variable with 0 to prevent an undefined behavior. This
+will be enough to handle error case when ar9300_otp_read_word() fails.
+
+Fixes: 80fe43f2bbd5 ("ath9k_hw: Read and configure thermocal for AR9462")
+Cc: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Cc: John W. Linville <linville@tuxdriver.com>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: stable@vger.kernel.org
+Signed-off-by: Denis Efremov <efremov@linux.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+@@ -4183,7 +4183,7 @@ static void ar9003_hw_thermometer_apply(
+ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
+ {
+-      u32 data, ko, kg;
++      u32 data = 0, ko, kg;
+       if (!AR_SREV_9462_20_OR_LATER(ah))
+               return;
index 1941af8c932fda1cd1792dd0749f706f0476be0b..9c136ee87bfeee059ed4756c9133d9227d0c1c55 100644 (file)
@@ -35,3 +35,7 @@ drm-i915-don-t-oops-in-dumb_create-ioctl-if-we-have-no-crtcs.patch
 drm-i915-pmu-frequency-is-reported-as-accumulated-cycles.patch
 drm-i915-userptr-try-to-acquire-the-page-lock-around-set_page_dirty.patch
 bluetooth-fix-invalid-free-in-bcsp_close.patch
+ath10k-restore-qca9880-ar1a-v1-detection.patch
+ath10k-fix-host-capability-qmi-incompatibility.patch
+ath10k-fix-a-null-ptr-deref-bug-in-ath10k_usb_alloc_urb_from_pipe.patch
+ath9k_hw-fix-uninitialized-variable-data.patch