From: Greg Kroah-Hartman Date: Sat, 29 May 2021 15:32:54 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.4.271~106 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b996add252eec56bff2085035532cb1a89c5d3b0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: ath10k-add-ccmp-pn-replay-protection-for-fragmented-frames-for-pcie.patch ath10k-drop-fragments-with-multicast-da-for-pcie.patch ath10k-drop-fragments-with-multicast-da-for-sdio.patch ath10k-drop-mpdu-which-has-discard-flag-set-by-firmware-for-sdio.patch ath10k-fix-tkip-michael-mic-verification-for-pcie.patch ath10k-validate-first-subframe-of-a-msdu-before-processing-the-list.patch dm-snapshot-properly-fix-a-crash-when-an-origin-has-no-snapshots.patch drm-amdgpu-vcn1-add-cancel_delayed_work_sync-before-power-gate.patch drm-amdgpu-vcn2.0-add-cancel_delayed_work_sync-before-power-gate.patch drm-amdgpu-vcn2.5-add-cancel_delayed_work_sync-before-power-gate.patch mac80211-do-not-accept-forward-invalid-eapol-frames.patch mac80211-extend-protection-against-mixed-key-and-fragment-cache-attacks.patch --- diff --git a/queue-5.4/ath10k-add-ccmp-pn-replay-protection-for-fragmented-frames-for-pcie.patch b/queue-5.4/ath10k-add-ccmp-pn-replay-protection-for-fragmented-frames-for-pcie.patch new file mode 100644 index 00000000000..300e2aa2327 --- /dev/null +++ b/queue-5.4/ath10k-add-ccmp-pn-replay-protection-for-fragmented-frames-for-pcie.patch @@ -0,0 +1,189 @@ +From a1166b2653db2f3de7338b9fb8a0f6e924b904ee Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:52 +0200 +Subject: ath10k: add CCMP PN replay protection for fragmented frames for PCIe + +From: Wen Gong + +commit a1166b2653db2f3de7338b9fb8a0f6e924b904ee upstream. + +PN replay check for not fragmented frames is finished in the firmware, +but this was not done for fragmented frames when ath10k is used with +QCA6174/QCA6377 PCIe. mac80211 has the function +ieee80211_rx_h_defragment() for PN replay check for fragmented frames, +but this does not get checked with QCA6174 due to the +ieee80211_has_protected() condition not matching the cleared Protected +bit case. + +Validate the PN of received fragmented frames within ath10k when CCMP is +used and drop the fragment if the PN is not correct (incremented by +exactly one from the previous fragment). This applies only for +QCA6174/QCA6377 PCIe. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.9ba2664866a4.I756e47b67e210dba69966d989c4711ffc02dc6bc@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt.h | 1 + drivers/net/wireless/ath/ath10k/htt_rx.c | 99 +++++++++++++++++++++++++++++-- + 2 files changed, 96 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/htt.h ++++ b/drivers/net/wireless/ath/ath10k/htt.h +@@ -835,6 +835,7 @@ enum htt_security_types { + + #define ATH10K_HTT_TXRX_PEER_SECURITY_MAX 2 + #define ATH10K_TXRX_NUM_EXT_TIDS 19 ++#define ATH10K_TXRX_NON_QOS_TID 16 + + enum htt_security_flags { + #define HTT_SECURITY_TYPE_MASK 0x7F +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -1739,16 +1739,87 @@ static void ath10k_htt_rx_h_csum_offload + msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); + } + ++static u64 ath10k_htt_rx_h_get_pn(struct ath10k *ar, struct sk_buff *skb, ++ u16 offset, ++ enum htt_rx_mpdu_encrypt_type enctype) ++{ ++ struct ieee80211_hdr *hdr; ++ u64 pn = 0; ++ u8 *ehdr; ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ ehdr = skb->data + offset + ieee80211_hdrlen(hdr->frame_control); ++ ++ if (enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) { ++ pn = ehdr[0]; ++ pn |= (u64)ehdr[1] << 8; ++ pn |= (u64)ehdr[4] << 16; ++ pn |= (u64)ehdr[5] << 24; ++ pn |= (u64)ehdr[6] << 32; ++ pn |= (u64)ehdr[7] << 40; ++ } ++ return pn; ++} ++ ++static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar, ++ struct sk_buff *skb, ++ u16 peer_id, ++ u16 offset, ++ enum htt_rx_mpdu_encrypt_type enctype) ++{ ++ struct ath10k_peer *peer; ++ union htt_rx_pn_t *last_pn, new_pn = {0}; ++ struct ieee80211_hdr *hdr; ++ bool more_frags; ++ u8 tid, frag_number; ++ u32 seq; ++ ++ peer = ath10k_peer_find_by_id(ar, peer_id); ++ if (!peer) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer for frag pn check\n"); ++ return false; ++ } ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ if (ieee80211_is_data_qos(hdr->frame_control)) ++ tid = ieee80211_get_tid(hdr); ++ else ++ tid = ATH10K_TXRX_NON_QOS_TID; ++ ++ last_pn = &peer->frag_tids_last_pn[tid]; ++ new_pn.pn48 = ath10k_htt_rx_h_get_pn(ar, skb, offset, enctype); ++ more_frags = ieee80211_has_morefrags(hdr->frame_control); ++ frag_number = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; ++ seq = (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; ++ ++ if (frag_number == 0) { ++ last_pn->pn48 = new_pn.pn48; ++ peer->frag_tids_seq[tid] = seq; ++ } else { ++ if (seq != peer->frag_tids_seq[tid]) ++ return false; ++ ++ if (new_pn.pn48 != last_pn->pn48 + 1) ++ return false; ++ ++ last_pn->pn48 = new_pn.pn48; ++ } ++ ++ return true; ++} ++ + static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *status, + bool fill_crypt_header, + u8 *rx_hdr, +- enum ath10k_pkt_rx_err *err) ++ enum ath10k_pkt_rx_err *err, ++ u16 peer_id, ++ bool frag) + { + struct sk_buff *first; + struct sk_buff *last; +- struct sk_buff *msdu; ++ struct sk_buff *msdu, *temp; + struct htt_rx_desc *rxd; + struct ieee80211_hdr *hdr; + enum htt_rx_mpdu_encrypt_type enctype; +@@ -1761,6 +1832,7 @@ static void ath10k_htt_rx_h_mpdu(struct + bool is_decrypted; + bool is_mgmt; + u32 attention; ++ bool frag_pn_check = true; + + if (skb_queue_empty(amsdu)) + return; +@@ -1859,6 +1931,24 @@ static void ath10k_htt_rx_h_mpdu(struct + } + + skb_queue_walk(amsdu, msdu) { ++ if (frag && !fill_crypt_header && is_decrypted && ++ enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) ++ frag_pn_check = ath10k_htt_rx_h_frag_pn_check(ar, ++ msdu, ++ peer_id, ++ 0, ++ enctype); ++ ++ if (!frag_pn_check) { ++ /* Discard the fragment with invalid PN */ ++ temp = msdu->prev; ++ __skb_unlink(msdu, amsdu); ++ dev_kfree_skb_any(msdu); ++ msdu = temp; ++ frag_pn_check = true; ++ continue; ++ } ++ + ath10k_htt_rx_h_csum_offload(msdu); + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, + is_decrypted); +@@ -2064,7 +2154,8 @@ static int ath10k_htt_rx_handle_amsdu(st + ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt); + + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter); +- ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err); ++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err, 0, ++ false); + msdus_to_queue = skb_queue_len(&amsdu); + ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); + +@@ -3014,7 +3105,7 @@ static int ath10k_htt_rx_in_ord_ind(stru + ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); + ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL); + ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL, +- NULL); ++ NULL, peer_id, frag); + ath10k_htt_rx_h_enqueue(ar, &amsdu, status); + break; + case -EAGAIN: diff --git a/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-pcie.patch b/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-pcie.patch new file mode 100644 index 00000000000..34047767830 --- /dev/null +++ b/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-pcie.patch @@ -0,0 +1,75 @@ +From 65c415a144ad8132b6a6d97d4a1919ffc728e2d1 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:53 +0200 +Subject: ath10k: drop fragments with multicast DA for PCIe + +From: Wen Gong + +commit 65c415a144ad8132b6a6d97d4a1919ffc728e2d1 upstream. + +Fragmentation is not used with multicast frames. Discard unexpected +fragments with multicast DA. This fixes CVE-2020-26145. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.5a0bd289bda8.Idd6ebea20038fb1cfee6de924aa595e5647c9eae@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -1761,6 +1761,16 @@ static u64 ath10k_htt_rx_h_get_pn(struct + return pn; + } + ++static bool ath10k_htt_rx_h_frag_multicast_check(struct ath10k *ar, ++ struct sk_buff *skb, ++ u16 offset) ++{ ++ struct ieee80211_hdr *hdr; ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ return !is_multicast_ether_addr(hdr->addr1); ++} ++ + static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar, + struct sk_buff *skb, + u16 peer_id, +@@ -1832,7 +1842,7 @@ static void ath10k_htt_rx_h_mpdu(struct + bool is_decrypted; + bool is_mgmt; + u32 attention; +- bool frag_pn_check = true; ++ bool frag_pn_check = true, multicast_check = true; + + if (skb_queue_empty(amsdu)) + return; +@@ -1939,13 +1949,20 @@ static void ath10k_htt_rx_h_mpdu(struct + 0, + enctype); + +- if (!frag_pn_check) { +- /* Discard the fragment with invalid PN */ ++ if (frag) ++ multicast_check = ath10k_htt_rx_h_frag_multicast_check(ar, ++ msdu, ++ 0); ++ ++ if (!frag_pn_check || !multicast_check) { ++ /* Discard the fragment with invalid PN or multicast DA ++ */ + temp = msdu->prev; + __skb_unlink(msdu, amsdu); + dev_kfree_skb_any(msdu); + msdu = temp; + frag_pn_check = true; ++ multicast_check = true; + continue; + } + diff --git a/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-sdio.patch b/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-sdio.patch new file mode 100644 index 00000000000..b648fbf97ca --- /dev/null +++ b/queue-5.4/ath10k-drop-fragments-with-multicast-da-for-sdio.patch @@ -0,0 +1,49 @@ +From 40e7462dad6f3d06efdb17d26539e61ab6e34db1 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:54 +0200 +Subject: ath10k: drop fragments with multicast DA for SDIO + +From: Wen Gong + +commit 40e7462dad6f3d06efdb17d26539e61ab6e34db1 upstream. + +Fragmentation is not used with multicast frames. Discard unexpected +fragments with multicast DA. This fixes CVE-2020-26145. + +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.9ca6ca7945a9.I1e18b514590af17c155bda86699bc3a971a8dcf4@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -2605,6 +2605,13 @@ static bool ath10k_htt_rx_proc_rx_frag_i + rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len); + rx_desc_info = __le32_to_cpu(rx_desc->info); + ++ hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); ++ ++ if (is_multicast_ether_addr(hdr->addr1)) { ++ /* Discard the fragment with multicast DA */ ++ goto err; ++ } ++ + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) { + spin_unlock_bh(&ar->data_lock); + return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, +@@ -2612,8 +2619,6 @@ static bool ath10k_htt_rx_proc_rx_frag_i + HTT_RX_NON_TKIP_MIC); + } + +- hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); +- + if (ieee80211_has_retry(hdr->frame_control)) + goto err; + diff --git a/queue-5.4/ath10k-drop-mpdu-which-has-discard-flag-set-by-firmware-for-sdio.patch b/queue-5.4/ath10k-drop-mpdu-which-has-discard-flag-set-by-firmware-for-sdio.patch new file mode 100644 index 00000000000..3c3f3ac49bb --- /dev/null +++ b/queue-5.4/ath10k-drop-mpdu-which-has-discard-flag-set-by-firmware-for-sdio.patch @@ -0,0 +1,63 @@ +From 079a108feba474b4b32bd3471db03e11f2f83b81 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:55 +0200 +Subject: ath10k: drop MPDU which has discard flag set by firmware for SDIO + +From: Wen Gong + +commit 079a108feba474b4b32bd3471db03e11f2f83b81 upstream. + +When the discard flag is set by the firmware for an MPDU, it should be +dropped. This allows a mitigation for CVE-2020-24588 to be implemented +in the firmware. + +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.11968c725b5c.Idd166365ebea2771c0c0a38c78b5060750f90e17@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 5 +++++ + drivers/net/wireless/ath/ath10k/rx_desc.h | 14 +++++++++++++- + 2 files changed, 18 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -2305,6 +2305,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl + fw_desc = &rx->fw_desc; + rx_desc_len = fw_desc->len; + ++ if (fw_desc->u.bits.discard) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n"); ++ goto err; ++ } ++ + /* I have not yet seen any case where num_mpdu_ranges > 1. + * qcacld does not seem handle that case either, so we introduce the + * same limitiation here as well. +--- a/drivers/net/wireless/ath/ath10k/rx_desc.h ++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h +@@ -1282,7 +1282,19 @@ struct fw_rx_desc_base { + #define FW_RX_DESC_UDP (1 << 6) + + struct fw_rx_desc_hl { +- u8 info0; ++ union { ++ struct { ++ u8 discard:1, ++ forward:1, ++ any_err:1, ++ dup_err:1, ++ reserved:1, ++ inspect:1, ++ extension:2; ++ } bits; ++ u8 info0; ++ } u; ++ + u8 version; + u8 len; + u8 flags; diff --git a/queue-5.4/ath10k-fix-tkip-michael-mic-verification-for-pcie.patch b/queue-5.4/ath10k-fix-tkip-michael-mic-verification-for-pcie.patch new file mode 100644 index 00000000000..02e474f12ca --- /dev/null +++ b/queue-5.4/ath10k-fix-tkip-michael-mic-verification-for-pcie.patch @@ -0,0 +1,57 @@ +From 0dc267b13f3a7e8424a898815dd357211b737330 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:56 +0200 +Subject: ath10k: Fix TKIP Michael MIC verification for PCIe + +From: Wen Gong + +commit 0dc267b13f3a7e8424a898815dd357211b737330 upstream. + +TKIP Michael MIC was not verified properly for PCIe cases since the +validation steps in ieee80211_rx_h_michael_mic_verify() in mac80211 did +not get fully executed due to unexpected flag values in +ieee80211_rx_status. + +Fix this by setting the flags property to meet mac80211 expectations for +performing Michael MIC validation there. This fixes CVE-2020-26141. It +does the same as ath10k_htt_rx_proc_rx_ind_hl() for SDIO which passed +MIC verification case. This applies only to QCA6174/QCA9377 PCIe. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.c3f1d42c6746.I795593fcaae941c471425b8c7d5f7bb185d29142@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -1967,6 +1967,11 @@ static void ath10k_htt_rx_h_mpdu(struct + } + + ath10k_htt_rx_h_csum_offload(msdu); ++ ++ if (frag && !fill_crypt_header && ++ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) ++ status->flag &= ~RX_FLAG_MMIC_STRIPPED; ++ + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, + is_decrypted); + +@@ -1984,6 +1989,11 @@ static void ath10k_htt_rx_h_mpdu(struct + + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); ++ ++ if (frag && !fill_crypt_header && ++ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) ++ status->flag &= ~RX_FLAG_IV_STRIPPED & ++ ~RX_FLAG_MMIC_STRIPPED; + } + } + diff --git a/queue-5.4/ath10k-validate-first-subframe-of-a-msdu-before-processing-the-list.patch b/queue-5.4/ath10k-validate-first-subframe-of-a-msdu-before-processing-the-list.patch new file mode 100644 index 00000000000..bfe9be2a085 --- /dev/null +++ b/queue-5.4/ath10k-validate-first-subframe-of-a-msdu-before-processing-the-list.patch @@ -0,0 +1,117 @@ +From 62a8ff67eba52dae9b107e1fb8827054ed00a265 Mon Sep 17 00:00:00 2001 +From: Sriram R +Date: Tue, 11 May 2021 20:02:57 +0200 +Subject: ath10k: Validate first subframe of A-MSDU before processing the list + +From: Sriram R + +commit 62a8ff67eba52dae9b107e1fb8827054ed00a265 upstream. + +In certain scenarios a normal MSDU can be received as an A-MSDU when +the A-MSDU present bit of a QoS header gets flipped during reception. +Since this bit is unauthenticated, the hardware crypto engine can pass +the frame to the driver without any error indication. + +This could result in processing unintended subframes collected in the +A-MSDU list. Hence, validate A-MSDU list by checking if the first frame +has a valid subframe header. + +Comparing the non-aggregated MSDU and an A-MSDU, the fields of the first +subframe DA matches the LLC/SNAP header fields of a normal MSDU. +In order to avoid processing such frames, add a validation to +filter such A-MSDU frames where the first subframe header DA matches +with the LLC/SNAP header pattern. + +Tested-on: QCA9984 hw1.0 PCI 10.4-3.10-00047 + +Cc: stable@vger.kernel.org +Signed-off-by: Sriram R +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.e6f5eb7b9847.I38a77ae26096862527a5eab73caebd7346af8b66@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath10k/htt_rx.c | 61 ++++++++++++++++++++++++++++--- + 1 file changed, 57 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -2101,14 +2101,62 @@ static void ath10k_htt_rx_h_unchain(stru + ath10k_unchain_msdu(amsdu, unchain_cnt); + } + ++static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar, ++ struct sk_buff_head *amsdu) ++{ ++ u8 *subframe_hdr; ++ struct sk_buff *first; ++ bool is_first, is_last; ++ struct htt_rx_desc *rxd; ++ struct ieee80211_hdr *hdr; ++ size_t hdr_len, crypto_len; ++ enum htt_rx_mpdu_encrypt_type enctype; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; ++ ++ first = skb_peek(amsdu); ++ ++ rxd = (void *)first->data - sizeof(*rxd); ++ hdr = (void *)rxd->rx_hdr_status; ++ ++ is_first = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); ++ is_last = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); ++ ++ /* Return in case of non-aggregated msdu */ ++ if (is_first && is_last) ++ return true; ++ ++ /* First msdu flag is not set for the first msdu of the list */ ++ if (!is_first) ++ return false; ++ ++ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), ++ RX_MPDU_START_INFO0_ENCRYPT_TYPE); ++ ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); ++ ++ subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) + ++ crypto_len; ++ ++ /* Validate if the amsdu has a proper first subframe. ++ * There are chances a single msdu can be received as amsdu when ++ * the unauthenticated amsdu flag of a QoS header ++ * gets flipped in non-SPP AMSDU's, in such cases the first ++ * subframe has llc/snap header in place of a valid da. ++ * return false if the da matches rfc1042 pattern ++ */ ++ if (ether_addr_equal(subframe_hdr, rfc1042_header)) ++ return false; ++ ++ return true; ++} ++ + static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *rx_status) + { +- /* FIXME: It might be a good idea to do some fuzzy-testing to drop +- * invalid/dangerous frames. +- */ +- + if (!rx_status->freq) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "no channel configured; ignoring frame(s)!\n"); + return false; +@@ -2119,6 +2167,11 @@ static bool ath10k_htt_rx_amsdu_allowed( + return false; + } + ++ if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n"); ++ return false; ++ } ++ + return true; + } + diff --git a/queue-5.4/dm-snapshot-properly-fix-a-crash-when-an-origin-has-no-snapshots.patch b/queue-5.4/dm-snapshot-properly-fix-a-crash-when-an-origin-has-no-snapshots.patch new file mode 100644 index 00000000000..7d080d5ac66 --- /dev/null +++ b/queue-5.4/dm-snapshot-properly-fix-a-crash-when-an-origin-has-no-snapshots.patch @@ -0,0 +1,35 @@ +From 7e768532b2396bcb7fbf6f82384b85c0f1d2f197 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Tue, 25 May 2021 13:17:19 -0400 +Subject: dm snapshot: properly fix a crash when an origin has no snapshots + +From: Mikulas Patocka + +commit 7e768532b2396bcb7fbf6f82384b85c0f1d2f197 upstream. + +If an origin target has no snapshots, o->split_boundary is set to 0. +This causes BUG_ON(sectors <= 0) in block/bio.c:bio_split(). + +Fix this by initializing chunk_size, and in turn split_boundary, to +rounddown_pow_of_two(UINT_MAX) -- the largest power of two that fits +into "unsigned" type. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-snap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -854,7 +854,7 @@ static int dm_add_exception(void *contex + static uint32_t __minimum_chunk_size(struct origin *o) + { + struct dm_snapshot *snap; +- unsigned chunk_size = 0; ++ unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); + + if (o) + list_for_each_entry(snap, &o->snapshots, list) diff --git a/queue-5.4/drm-amdgpu-vcn1-add-cancel_delayed_work_sync-before-power-gate.patch b/queue-5.4/drm-amdgpu-vcn1-add-cancel_delayed_work_sync-before-power-gate.patch new file mode 100644 index 00000000000..866073dc12c --- /dev/null +++ b/queue-5.4/drm-amdgpu-vcn1-add-cancel_delayed_work_sync-before-power-gate.patch @@ -0,0 +1,42 @@ +From b95f045ea35673572ef46d6483ad8bd6d353d63c Mon Sep 17 00:00:00 2001 +From: James Zhu +Date: Tue, 18 May 2021 10:58:22 -0400 +Subject: drm/amdgpu/vcn1: add cancel_delayed_work_sync before power gate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Zhu + +commit b95f045ea35673572ef46d6483ad8bd6d353d63c upstream. + +Add cancel_delayed_work_sync before set power gating state +to avoid race condition issue when power gating. + +Signed-off-by: James Zhu +Reviewed-by: Leo Liu +Acked-by: Christian König +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +@@ -233,9 +233,13 @@ static int vcn_v1_0_hw_fini(void *handle + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || +- RREG32_SOC15(VCN, 0, mmUVD_STATUS)) ++ (adev->vcn.cur_state != AMD_PG_STATE_GATE && ++ RREG32_SOC15(VCN, 0, mmUVD_STATUS))) { + vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); ++ } + + ring->sched.ready = false; + diff --git a/queue-5.4/drm-amdgpu-vcn2.0-add-cancel_delayed_work_sync-before-power-gate.patch b/queue-5.4/drm-amdgpu-vcn2.0-add-cancel_delayed_work_sync-before-power-gate.patch new file mode 100644 index 00000000000..c7907575d67 --- /dev/null +++ b/queue-5.4/drm-amdgpu-vcn2.0-add-cancel_delayed_work_sync-before-power-gate.patch @@ -0,0 +1,36 @@ +From 0c6013377b4027e69d8f3e63b6bf556b6cb87802 Mon Sep 17 00:00:00 2001 +From: James Zhu +Date: Wed, 19 May 2021 11:26:32 -0400 +Subject: drm/amdgpu/vcn2.0: add cancel_delayed_work_sync before power gate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Zhu + +commit 0c6013377b4027e69d8f3e63b6bf556b6cb87802 upstream. + +Add cancel_delayed_work_sync before set power gating state +to avoid race condition issue when power gating. + +Signed-off-by: James Zhu +Reviewed-by: Leo Liu +Acked-by: Christian König +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +@@ -293,6 +293,8 @@ static int vcn_v2_0_hw_fini(void *handle + struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || + (adev->vcn.cur_state != AMD_PG_STATE_GATE && + RREG32_SOC15(VCN, 0, mmUVD_STATUS))) diff --git a/queue-5.4/drm-amdgpu-vcn2.5-add-cancel_delayed_work_sync-before-power-gate.patch b/queue-5.4/drm-amdgpu-vcn2.5-add-cancel_delayed_work_sync-before-power-gate.patch new file mode 100644 index 00000000000..033977ce20a --- /dev/null +++ b/queue-5.4/drm-amdgpu-vcn2.5-add-cancel_delayed_work_sync-before-power-gate.patch @@ -0,0 +1,36 @@ +From 2fb536ea42d557f39f70c755f68e1aa1ad466c55 Mon Sep 17 00:00:00 2001 +From: James Zhu +Date: Wed, 19 May 2021 11:40:39 -0400 +Subject: drm/amdgpu/vcn2.5: add cancel_delayed_work_sync before power gate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Zhu + +commit 2fb536ea42d557f39f70c755f68e1aa1ad466c55 upstream. + +Add cancel_delayed_work_sync before set power gating state +to avoid race condition issue when power gating. + +Signed-off-by: James Zhu +Reviewed-by: Leo Liu +Acked-by: Christian König +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +@@ -302,6 +302,8 @@ static int vcn_v2_5_hw_fini(void *handle + struct amdgpu_ring *ring; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) + continue; diff --git a/queue-5.4/mac80211-do-not-accept-forward-invalid-eapol-frames.patch b/queue-5.4/mac80211-do-not-accept-forward-invalid-eapol-frames.patch new file mode 100644 index 00000000000..8d374d5b716 --- /dev/null +++ b/queue-5.4/mac80211-do-not-accept-forward-invalid-eapol-frames.patch @@ -0,0 +1,103 @@ +From a8c4d76a8dd4fb9666fc8919a703d85fb8f44ed8 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 11 May 2021 20:02:50 +0200 +Subject: mac80211: do not accept/forward invalid EAPOL frames + +From: Johannes Berg + +commit a8c4d76a8dd4fb9666fc8919a703d85fb8f44ed8 upstream. + +EAPOL frames are used for authentication and key management between the +AP and each individual STA associated in the BSS. Those frames are not +supposed to be sent by one associated STA to another associated STA +(either unicast for broadcast/multicast). + +Similarly, in 802.11 they're supposed to be sent to the authenticator +(AP) address. + +Since it is possible for unexpected EAPOL frames to result in misbehavior +in supplicant implementations, it is better for the AP to not allow such +cases to be forwarded to other clients either directly, or indirectly if +the AP interface is part of a bridge. + +Accept EAPOL (control port) frames only if they're transmitted to the +own address, or, due to interoperability concerns, to the PAE group +address. + +Disable forwarding of EAPOL (or well, the configured control port +protocol) frames back to wireless medium in all cases. Previously, these +frames were accepted from fully authenticated and authorized stations +and also from unauthenticated stations for one of the cases. + +Additionally, to avoid forwarding by the bridge, rewrite the PAE group +address case to the local MAC address. + +Cc: stable@vger.kernel.org +Co-developed-by: Jouni Malinen +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.cb327ed0cabe.Ib7dcffa2a31f0913d660de65ba3c8aca75b1d10f@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/rx.c | 33 +++++++++++++++++++++++++++------ + 1 file changed, 27 insertions(+), 6 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2484,13 +2484,13 @@ static bool ieee80211_frame_allowed(stru + struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; + + /* +- * Allow EAPOL frames to us/the PAE group address regardless +- * of whether the frame was encrypted or not. ++ * Allow EAPOL frames to us/the PAE group address regardless of ++ * whether the frame was encrypted or not, and always disallow ++ * all other destination addresses for them. + */ +- if (ehdr->h_proto == rx->sdata->control_port_protocol && +- (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || +- ether_addr_equal(ehdr->h_dest, pae_group_addr))) +- return true; ++ if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol)) ++ return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || ++ ether_addr_equal(ehdr->h_dest, pae_group_addr); + + if (ieee80211_802_1x_port_control(rx) || + ieee80211_drop_unencrypted(rx, fc)) +@@ -2514,8 +2514,28 @@ static void ieee80211_deliver_skb_to_loc + cfg80211_rx_control_port(dev, skb, noencrypt); + dev_kfree_skb(skb); + } else { ++ struct ethhdr *ehdr = (void *)skb_mac_header(skb); ++ + memset(skb->cb, 0, sizeof(skb->cb)); + ++ /* ++ * 802.1X over 802.11 requires that the authenticator address ++ * be used for EAPOL frames. However, 802.1X allows the use of ++ * the PAE group address instead. If the interface is part of ++ * a bridge and we pass the frame with the PAE group address, ++ * then the bridge will forward it to the network (even if the ++ * client was not associated yet), which isn't supposed to ++ * happen. ++ * To avoid that, rewrite the destination address to our own ++ * address, so that the authenticator (e.g. hostapd) will see ++ * the frame, but bridge won't forward it anywhere else. Note ++ * that due to earlier filtering, the only other address can ++ * be the PAE group address. ++ */ ++ if (unlikely(skb->protocol == sdata->control_port_protocol && ++ !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) ++ ether_addr_copy(ehdr->h_dest, sdata->vif.addr); ++ + /* deliver to local stack */ + if (rx->napi) + napi_gro_receive(rx->napi, skb); +@@ -2555,6 +2575,7 @@ ieee80211_deliver_skb(struct ieee80211_r + if ((sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && + !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && ++ ehdr->h_proto != rx->sdata->control_port_protocol && + (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { + if (is_multicast_ether_addr(ehdr->h_dest) && + ieee80211_vif_get_num_mcast_if(sdata) != 0) { diff --git a/queue-5.4/mac80211-extend-protection-against-mixed-key-and-fragment-cache-attacks.patch b/queue-5.4/mac80211-extend-protection-against-mixed-key-and-fragment-cache-attacks.patch new file mode 100644 index 00000000000..110cdba9a17 --- /dev/null +++ b/queue-5.4/mac80211-extend-protection-against-mixed-key-and-fragment-cache-attacks.patch @@ -0,0 +1,76 @@ +From 3edc6b0d6c061a70d8ca3c3c72eb1f58ce29bfb1 Mon Sep 17 00:00:00 2001 +From: Wen Gong +Date: Tue, 11 May 2021 20:02:51 +0200 +Subject: mac80211: extend protection against mixed key and fragment cache attacks + +From: Wen Gong + +commit 3edc6b0d6c061a70d8ca3c3c72eb1f58ce29bfb1 upstream. + +For some chips/drivers, e.g., QCA6174 with ath10k, the decryption is +done by the hardware, and the Protected bit in the Frame Control field +is cleared in the lower level driver before the frame is passed to +mac80211. In such cases, the condition for ieee80211_has_protected() is +not met in ieee80211_rx_h_defragment() of mac80211 and the new security +validation steps are not executed. + +Extend mac80211 to cover the case where the Protected bit has been +cleared, but the frame is indicated as having been decrypted by the +hardware. This extends protection against mixed key and fragment cache +attack for additional drivers/chips. This fixes CVE-2020-24586 and +CVE-2020-24587 for such cases. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1 + +Cc: stable@vger.kernel.org +Signed-off-by: Wen Gong +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20210511200110.037aa5ca0390.I7bb888e2965a0db02a67075fcb5deb50eb7408aa@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/rx.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2189,6 +2189,7 @@ ieee80211_rx_h_defragment(struct ieee802 + unsigned int frag, seq; + struct ieee80211_fragment_entry *entry; + struct sk_buff *skb; ++ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + hdr = (struct ieee80211_hdr *)rx->skb->data; + fc = hdr->frame_control; +@@ -2247,7 +2248,9 @@ ieee80211_rx_h_defragment(struct ieee802 + sizeof(rx->key->u.gcmp.rx_pn[queue])); + BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN != + IEEE80211_GCMP_PN_LEN); +- } else if (rx->key && ieee80211_has_protected(fc)) { ++ } else if (rx->key && ++ (ieee80211_has_protected(fc) || ++ (status->flag & RX_FLAG_DECRYPTED))) { + entry->is_protected = true; + entry->key_color = rx->key->color; + } +@@ -2292,13 +2295,19 @@ ieee80211_rx_h_defragment(struct ieee802 + return RX_DROP_UNUSABLE; + memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); + } else if (entry->is_protected && +- (!rx->key || !ieee80211_has_protected(fc) || ++ (!rx->key || ++ (!ieee80211_has_protected(fc) && ++ !(status->flag & RX_FLAG_DECRYPTED)) || + rx->key->color != entry->key_color)) { + /* Drop this as a mixed key or fragment cache attack, even + * if for TKIP Michael MIC should protect us, and WEP is a + * lost cause anyway. + */ + return RX_DROP_UNUSABLE; ++ } else if (entry->is_protected && rx->key && ++ entry->key_color != rx->key->color && ++ (status->flag & RX_FLAG_DECRYPTED)) { ++ return RX_DROP_UNUSABLE; + } + + skb_pull(rx->skb, ieee80211_hdrlen(fc)); diff --git a/queue-5.4/series b/queue-5.4/series index 103246be5ac..17dcc0e2db3 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -19,6 +19,18 @@ mac80211-drop-a-msdus-on-old-ciphers.patch mac80211-add-fragment-cache-to-sta_info.patch mac80211-check-defrag-pn-against-current-frame.patch mac80211-prevent-attacks-on-tkip-wep-as-well.patch +mac80211-do-not-accept-forward-invalid-eapol-frames.patch +mac80211-extend-protection-against-mixed-key-and-fragment-cache-attacks.patch +ath10k-add-ccmp-pn-replay-protection-for-fragmented-frames-for-pcie.patch +ath10k-drop-fragments-with-multicast-da-for-pcie.patch +ath10k-drop-fragments-with-multicast-da-for-sdio.patch +ath10k-drop-mpdu-which-has-discard-flag-set-by-firmware-for-sdio.patch +ath10k-fix-tkip-michael-mic-verification-for-pcie.patch +ath10k-validate-first-subframe-of-a-msdu-before-processing-the-list.patch +dm-snapshot-properly-fix-a-crash-when-an-origin-has-no-snapshots.patch +drm-amdgpu-vcn1-add-cancel_delayed_work_sync-before-power-gate.patch +drm-amdgpu-vcn2.0-add-cancel_delayed_work_sync-before-power-gate.patch +drm-amdgpu-vcn2.5-add-cancel_delayed_work_sync-before-power-gate.patch selftests-gpio-use-test_gen_progs_extended.patch selftests-gpio-move-include-of-lib.mk-up.patch selftests-gpio-fix-build-when-source-tree-is-read-on.patch