--- /dev/null
+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));
--- /dev/null
+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)
--- /dev/null
+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;
+ }