From: Greg Kroah-Hartman Date: Mon, 16 Mar 2020 14:27:38 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.19.111~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5b2b7638e919655419aaff9d2e845a6ed8ca29f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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 --- 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 index 00000000000..b8e3371f835 --- /dev/null +++ b/queue-4.9/iommu-vt-d-fix-the-wrong-printing-in-rhsa-parsing.patch @@ -0,0 +1,36 @@ +From b0bb0c22c4db623f2e7b1a471596fbf1c22c6dc5 Mon Sep 17 00:00:00 2001 +From: Zhenzhong Duan +Date: Thu, 12 Mar 2020 14:09:54 +0800 +Subject: iommu/vt-d: Fix the wrong printing in RHSA parsing + +From: Zhenzhong Duan + +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 +Signed-off-by: Zhenzhong Duan +Fixes: fd0c8894893cb ("intel-iommu: Set a more specific taint flag for invalid BIOS DMAR tables") +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..98a10d41dba --- /dev/null +++ b/queue-4.9/iommu-vt-d-ignore-devices-with-out-of-spec-domain-number.patch @@ -0,0 +1,70 @@ +From da72a379b2ec0bad3eb265787f7008bead0b040c Mon Sep 17 00:00:00 2001 +From: Daniel Drake +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 + +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 +Signed-off-by: Daniel Drake +Fixes: 59ce0515cdaf3 ("iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens") +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 index 00000000000..900297ca089 --- /dev/null +++ b/queue-4.9/mwifiex-fix-heap-overflow-in-mmwifiex_process_tdls_action_frame.patch @@ -0,0 +1,162 @@ +From 1e58252e334dc3f3756f424a157d1b7484464c40 Mon Sep 17 00:00:00 2001 +From: qize wang +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 + +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 +Signed-off-by: Kalle Valo +Signed-off-by: Matthias Maennich +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.9/series b/queue-4.9/series index b94408fab17..b8b3d6b3f5e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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