]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2020 14:27:38 +0000 (15:27 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2020 14:27:38 +0000 (15:27 +0100)
added patches:
iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch
iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch
mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch

queue-4.9/iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch [new file with mode: 0644]
queue-4.9/iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch [new file with mode: 0644]
queue-4.9/mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch b/queue-4.9/iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch
new file mode 100644 (file)
index 0000000..b8e3371
--- /dev/null
@@ -0,0 +1,36 @@
+From b0bb0c22c4db623f2e7b1a471596fbf1c22c6dc5 Mon Sep 17 00:00:00 2001
+From: Zhenzhong Duan <zhenzhong.duan@gmail.com>
+Date: Thu, 12 Mar 2020 14:09:54 +0800
+Subject: iommu/vt-d: Fix the wrong printing in RHSA parsing
+
+From: Zhenzhong Duan <zhenzhong.duan@gmail.com>
+
+commit b0bb0c22c4db623f2e7b1a471596fbf1c22c6dc5 upstream.
+
+When base address in RHSA structure doesn't match base address in
+each DRHD structure, the base address in last DRHD is printed out.
+
+This doesn't make sense when there are multiple DRHD units, fix it
+by printing the buggy RHSA's base address.
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Zhenzhong Duan <zhenzhong.duan@gmail.com>
+Fixes: fd0c8894893cb ("intel-iommu: Set a more specific taint flag for invalid BIOS DMAR tables")
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/dmar.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iommu/dmar.c
++++ b/drivers/iommu/dmar.c
+@@ -485,7 +485,7 @@ static int dmar_parse_one_rhsa(struct ac
+       pr_warn(FW_BUG
+               "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n"
+               "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+-              drhd->reg_base_addr,
++              rhsa->base_address,
+               dmi_get_system_info(DMI_BIOS_VENDOR),
+               dmi_get_system_info(DMI_BIOS_VERSION),
+               dmi_get_system_info(DMI_PRODUCT_VERSION));
diff --git a/queue-4.9/iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch b/queue-4.9/iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch
new file mode 100644 (file)
index 0000000..98a10d4
--- /dev/null
@@ -0,0 +1,70 @@
+From da72a379b2ec0bad3eb265787f7008bead0b040c Mon Sep 17 00:00:00 2001
+From: Daniel Drake <drake@endlessm.com>
+Date: Thu, 12 Mar 2020 14:09:55 +0800
+Subject: iommu/vt-d: Ignore devices with out-of-spec domain number
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Drake <drake@endlessm.com>
+
+commit da72a379b2ec0bad3eb265787f7008bead0b040c upstream.
+
+VMD subdevices are created with a PCI domain ID of 0x10000 or
+higher.
+
+These subdevices are also handled like all other PCI devices by
+dmar_pci_bus_notifier().
+
+However, when dmar_alloc_pci_notify_info() take records of such devices,
+it will truncate the domain ID to a u16 value (in info->seg).
+The device at (e.g.) 10000:00:02.0 is then treated by the DMAR code as if
+it is 0000:00:02.0.
+
+In the unlucky event that a real device also exists at 0000:00:02.0 and
+also has a device-specific entry in the DMAR table,
+dmar_insert_dev_scope() will crash on:
+   BUG_ON(i >= devices_cnt);
+
+That's basically a sanity check that only one PCI device matches a
+single DMAR entry; in this case we seem to have two matching devices.
+
+Fix this by ignoring devices that have a domain number higher than
+what can be looked up in the DMAR table.
+
+This problem was carefully diagnosed by Jian-Hong Pan.
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Daniel Drake <drake@endlessm.com>
+Fixes: 59ce0515cdaf3 ("iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens")
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/dmar.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/iommu/dmar.c
++++ b/drivers/iommu/dmar.c
+@@ -39,6 +39,7 @@
+ #include <linux/dmi.h>
+ #include <linux/slab.h>
+ #include <linux/iommu.h>
++#include <linux/limits.h>
+ #include <asm/irq_remapping.h>
+ #include <asm/iommu_table.h>
+@@ -138,6 +139,13 @@ dmar_alloc_pci_notify_info(struct pci_de
+       BUG_ON(dev->is_virtfn);
++      /*
++       * Ignore devices that have a domain number higher than what can
++       * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
++       */
++      if (pci_domain_nr(dev->bus) > U16_MAX)
++              return NULL;
++
+       /* Only generate path[] for device addition event */
+       if (event == BUS_NOTIFY_ADD_DEVICE)
+               for (tmp = dev; tmp; tmp = tmp->bus->self)
diff --git a/queue-4.9/mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch b/queue-4.9/mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch
new file mode 100644 (file)
index 0000000..900297c
--- /dev/null
@@ -0,0 +1,162 @@
+From 1e58252e334dc3f3756f424a157d1b7484464c40 Mon Sep 17 00:00:00 2001
+From: qize wang <wangqize888888888@gmail.com>
+Date: Fri, 29 Nov 2019 18:10:54 +0800
+Subject: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: qize wang <wangqize888888888@gmail.com>
+
+commit 1e58252e334dc3f3756f424a157d1b7484464c40 upstream.
+
+mwifiex_process_tdls_action_frame() without checking
+the incoming tdls infomation element's vality before use it,
+this may cause multi heap buffer overflows.
+
+Fix them by putting vality check before use it.
+
+IE is TLV struct, but ht_cap and  ht_oper aren’t TLV struct.
+the origin marvell driver code is wrong:
+
+memcpy(&sta_ptr->tdls_cap.ht_oper, pos,....
+memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,...
+
+Fix the bug by changing pos(the address of IE) to
+pos+2 ( the address of IE value ).
+
+Signed-off-by: qize wang <wangqize888888888@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Matthias Maennich <maennich@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/marvell/mwifiex/tdls.c |   70 +++++++++++++++++++++++++---
+ 1 file changed, 64 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
+@@ -917,59 +917,117 @@ void mwifiex_process_tdls_action_frame(s
+               switch (*pos) {
+               case WLAN_EID_SUPP_RATES:
++                      if (pos[1] > 32)
++                              return;
+                       sta_ptr->tdls_cap.rates_len = pos[1];
+                       for (i = 0; i < pos[1]; i++)
+                               sta_ptr->tdls_cap.rates[i] = pos[i + 2];
+                       break;
+               case WLAN_EID_EXT_SUPP_RATES:
++                      if (pos[1] > 32)
++                              return;
+                       basic = sta_ptr->tdls_cap.rates_len;
++                      if (pos[1] > 32 - basic)
++                              return;
+                       for (i = 0; i < pos[1]; i++)
+                               sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
+                       sta_ptr->tdls_cap.rates_len += pos[1];
+                       break;
+               case WLAN_EID_HT_CAPABILITY:
+-                      memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,
++                      if (pos > end - sizeof(struct ieee80211_ht_cap) - 2)
++                              return;
++                      if (pos[1] != sizeof(struct ieee80211_ht_cap))
++                              return;
++                      /* copy the ie's value into ht_capb*/
++                      memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
+                              sizeof(struct ieee80211_ht_cap));
+                       sta_ptr->is_11n_enabled = 1;
+                       break;
+               case WLAN_EID_HT_OPERATION:
+-                      memcpy(&sta_ptr->tdls_cap.ht_oper, pos,
++                      if (pos > end -
++                          sizeof(struct ieee80211_ht_operation) - 2)
++                              return;
++                      if (pos[1] != sizeof(struct ieee80211_ht_operation))
++                              return;
++                      /* copy the ie's value into ht_oper*/
++                      memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
+                              sizeof(struct ieee80211_ht_operation));
+                       break;
+               case WLAN_EID_BSS_COEX_2040:
++                      if (pos > end - 3)
++                              return;
++                      if (pos[1] != 1)
++                              return;
+                       sta_ptr->tdls_cap.coex_2040 = pos[2];
+                       break;
+               case WLAN_EID_EXT_CAPABILITY:
++                      if (pos > end - sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] < sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] > 8)
++                              return;
+                       memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
+                              sizeof(struct ieee_types_header) +
+                              min_t(u8, pos[1], 8));
+                       break;
+               case WLAN_EID_RSN:
++                      if (pos > end - sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] < sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] > IEEE_MAX_IE_SIZE -
++                          sizeof(struct ieee_types_header))
++                              return;
+                       memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
+                              sizeof(struct ieee_types_header) +
+                              min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
+                                    sizeof(struct ieee_types_header)));
+                       break;
+               case WLAN_EID_QOS_CAPA:
++                      if (pos > end - 3)
++                              return;
++                      if (pos[1] != 1)
++                              return;
+                       sta_ptr->tdls_cap.qos_info = pos[2];
+                       break;
+               case WLAN_EID_VHT_OPERATION:
+-                      if (priv->adapter->is_hw_11ac_capable)
+-                              memcpy(&sta_ptr->tdls_cap.vhtoper, pos,
++                      if (priv->adapter->is_hw_11ac_capable) {
++                              if (pos > end -
++                                  sizeof(struct ieee80211_vht_operation) - 2)
++                                      return;
++                              if (pos[1] !=
++                                  sizeof(struct ieee80211_vht_operation))
++                                      return;
++                              /* copy the ie's value into vhtoper*/
++                              memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
+                                      sizeof(struct ieee80211_vht_operation));
++                      }
+                       break;
+               case WLAN_EID_VHT_CAPABILITY:
+                       if (priv->adapter->is_hw_11ac_capable) {
+-                              memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos,
++                              if (pos > end -
++                                  sizeof(struct ieee80211_vht_cap) - 2)
++                                      return;
++                              if (pos[1] != sizeof(struct ieee80211_vht_cap))
++                                      return;
++                              /* copy the ie's value into vhtcap*/
++                              memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
+                                      sizeof(struct ieee80211_vht_cap));
+                               sta_ptr->is_11ac_enabled = 1;
+                       }
+                       break;
+               case WLAN_EID_AID:
+-                      if (priv->adapter->is_hw_11ac_capable)
++                      if (priv->adapter->is_hw_11ac_capable) {
++                              if (pos > end - 4)
++                                      return;
++                              if (pos[1] != 2)
++                                      return;
+                               sta_ptr->tdls_cap.aid =
+                                             le16_to_cpu(*(__le16 *)(pos + 2));
++                      }
++                      break;
+               default:
+                       break;
+               }
index b94408fab17c880811eb4ef16c5ccb04d360a750..b8b3d6b3f5e614322c6104fb92182fd1639a48d8 100644 (file)
@@ -44,3 +44,6 @@ nl80211-add-missing-attribute-validation-for-critical-protocol-indication.patch
 nl80211-add-missing-attribute-validation-for-beacon-report-scanning.patch
 nl80211-add-missing-attribute-validation-for-channel-switch.patch
 netfilter-cthelper-add-missing-attribute-validation-for-cthelper.patch
+mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch
+iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch
+iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch