mac80211: Update to backports-5.10.42
The removed patches were integrated upstream. The brcmf_driver_work workqueue was removed in brcmfmac with kernel 5.10.42, the asynchronous call was covered to a synchronous call. There is no need to wait any more. This part was removed manually from this patch: brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		| @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk | |||||||
|  |  | ||||||
| PKG_NAME:=mac80211 | PKG_NAME:=mac80211 | ||||||
|  |  | ||||||
| PKG_VERSION:=5.10.34-1 | PKG_VERSION:=5.10.42-1 | ||||||
| PKG_RELEASE:=1 | PKG_RELEASE:=1 | ||||||
| PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.34/ | PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.42/ | ||||||
| PKG_HASH:=03c4ca6bf47d4e50b91b61bc2943a98c788439e56ce2b4080bc4c94141c2c15b | PKG_HASH:=6876520105240844fdb32d1dcdf2bfdea291a37a96f16c892fda3776ba714fcb | ||||||
|  |  | ||||||
| PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz | ||||||
| PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) | ||||||
|   | |||||||
| @@ -82,7 +82,7 @@ | |||||||
|  	help |  	help | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -86,6 +86,7 @@ ADM8211= | @@ -85,6 +85,7 @@ ADM8211= | ||||||
|  ATH_COMMON= |  ATH_COMMON= | ||||||
|  WLAN_VENDOR_ATH= |  WLAN_VENDOR_ATH= | ||||||
|  ATH_DEBUG= |  ATH_DEBUG= | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ | |||||||
|  void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); |  void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -143,6 +143,7 @@ ATH10K_SNOC= | @@ -144,6 +144,7 @@ ATH10K_SNOC= | ||||||
|  ATH10K_DEBUG= |  ATH10K_DEBUG= | ||||||
|  ATH10K_DEBUGFS= |  ATH10K_DEBUGFS= | ||||||
|  ATH10K_SPECTRAL= |  ATH10K_SPECTRAL= | ||||||
|   | |||||||
| @@ -1,180 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:52 +0200 |  | ||||||
| Subject: [PATCH] ath10k: add CCMP PN replay protection for fragmented |  | ||||||
|  frames for PCIe |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt.h |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt.h |  | ||||||
| @@ -846,6 +846,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 |  | ||||||
| @@ -1746,16 +1746,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; |  | ||||||
| @@ -1768,6 +1839,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; |  | ||||||
| @@ -1866,6 +1938,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); |  | ||||||
| @@ -2071,7 +2161,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); |  | ||||||
|   |  | ||||||
| @@ -3027,7 +3118,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: |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:53 +0200 |  | ||||||
| Subject: [PATCH] ath10k: drop fragments with multicast DA for PCIe |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| @@ -1768,6 +1768,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, |  | ||||||
| @@ -1839,7 +1849,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; |  | ||||||
| @@ -1946,13 +1956,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; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
| @@ -1,40 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:54 +0200 |  | ||||||
| Subject: [PATCH] ath10k: drop fragments with multicast DA for SDIO |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| @@ -2617,6 +2617,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, |  | ||||||
| @@ -2624,8 +2631,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; |  | ||||||
|   |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:55 +0200 |  | ||||||
| Subject: [PATCH] ath10k: drop MPDU which has discard flag set by firmware |  | ||||||
|  for SDIO |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| @@ -2312,6 +2312,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; |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:56 +0200 |  | ||||||
| Subject: [PATCH] ath10k: Fix TKIP Michael MIC verification for PCIe |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| @@ -1974,6 +1974,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); |  | ||||||
|   |  | ||||||
| @@ -1991,6 +1996,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; |  | ||||||
|  	} |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,109 +0,0 @@ | |||||||
| From: Sriram R <srirrama@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:57 +0200 |  | ||||||
| Subject: [PATCH] ath10k: Validate first subframe of A-MSDU before |  | ||||||
|  processing the list |  | ||||||
|  |  | ||||||
| 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 <srirrama@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c |  | ||||||
| @@ -2108,14 +2108,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; |  | ||||||
| @@ -2126,6 +2174,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; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -114,7 +114,7 @@ v13: | |||||||
|  ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o |  ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -146,6 +146,7 @@ ATH10K_DEBUG= | @@ -145,6 +145,7 @@ ATH10K_DEBUG= | ||||||
|  ATH10K_DEBUGFS= |  ATH10K_DEBUGFS= | ||||||
|  ATH10K_SPECTRAL= |  ATH10K_SPECTRAL= | ||||||
|  ATH10K_THERMAL= |  ATH10K_THERMAL= | ||||||
| @@ -456,7 +456,7 @@ v13: | |||||||
|  { |  { | ||||||
| --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c | --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c | ||||||
| +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c | ||||||
| @@ -4591,6 +4591,8 @@ static const struct wmi_ops wmi_tlv_ops | @@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops | ||||||
|  	.gen_echo = ath10k_wmi_tlv_op_gen_echo, |  	.gen_echo = ath10k_wmi_tlv_op_gen_echo, | ||||||
|  	.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, |  	.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, | ||||||
|  	.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, |  	.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, | ||||||
|   | |||||||
| @@ -371,7 +371,7 @@ | |||||||
|   |   | ||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -113,6 +113,7 @@ ATH9K_WOW= | @@ -112,6 +112,7 @@ ATH9K_WOW= | ||||||
|  ATH9K_RFKILL= |  ATH9K_RFKILL= | ||||||
|  ATH9K_CHANNEL_CONTEXT= |  ATH9K_CHANNEL_CONTEXT= | ||||||
|  ATH9K_PCOEM= |  ATH9K_PCOEM= | ||||||
|   | |||||||
| @@ -11,16 +11,6 @@ module loads successfully. | |||||||
| Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
| --- | --- | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c |  | ||||||
| @@ -1557,6 +1557,7 @@ int __init brcmf_core_init(void) |  | ||||||
|  { |  | ||||||
|  	if (!schedule_work(&brcmf_driver_work)) |  | ||||||
|  		return -EBUSY; |  | ||||||
| +	flush_work(&brcmf_driver_work); |  | ||||||
|   |  | ||||||
|  	return 0; |  | ||||||
|  } |  | ||||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||||
| @@ -431,6 +431,7 @@ struct brcmf_fw { | @@ -431,6 +431,7 @@ struct brcmf_fw { | ||||||
|   | |||||||
| @@ -55,8 +55,8 @@ | |||||||
| -				echo ""							;\ | -				echo ""							;\ | ||||||
| -			done								\ | -			done								\ | ||||||
| -		) > Kconfig.kernel							;\ | -		) > Kconfig.kernel							;\ | ||||||
| -		kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion |	\ | -		kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR)	\ | ||||||
| -			sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d')		;\ | -			kernelversion |	sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ | ||||||
| -		test "$$kver" != "" || echo "Kernel version parse failed!"		;\ | -		test "$$kver" != "" || echo "Kernel version parse failed!"		;\ | ||||||
| -		test "$$kver" != ""							;\ | -		test "$$kver" != ""							;\ | ||||||
| -		kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\ | -		kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\ | ||||||
| @@ -112,8 +112,8 @@ | |||||||
| +	@echo " done." | +	@echo " done." | ||||||
| + | + | ||||||
| +Kconfig.versions: Kconfig.kernel | +Kconfig.versions: Kconfig.kernel | ||||||
| +	@kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion |	\ | +	@kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ | ||||||
| +		sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d')		;\ | +		kernelversion |	sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ | ||||||
| +	test "$$kver" != "" || echo "Kernel version parse failed!"		;\ | +	test "$$kver" != "" || echo "Kernel version parse failed!"		;\ | ||||||
| +	test "$$kver" != ""							;\ | +	test "$$kver" != ""							;\ | ||||||
| +	kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\ | +	kvers="$$(seq 14 39 | sed 's/^/2.6./')"					;\ | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/drivers/net/wireless/marvell/mwl8k.c | --- a/drivers/net/wireless/marvell/mwl8k.c | ||||||
| +++ b/drivers/net/wireless/marvell/mwl8k.c | +++ b/drivers/net/wireless/marvell/mwl8k.c | ||||||
| @@ -5694,6 +5694,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") | @@ -5695,6 +5695,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") | ||||||
|  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); |  MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); | ||||||
|   |   | ||||||
|  static const struct pci_device_id mwl8k_pci_id_table[] = { |  static const struct pci_device_id mwl8k_pci_id_table[] = { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/drivers/net/wireless/marvell/mwl8k.c | --- a/drivers/net/wireless/marvell/mwl8k.c | ||||||
| +++ b/drivers/net/wireless/marvell/mwl8k.c | +++ b/drivers/net/wireless/marvell/mwl8k.c | ||||||
| @@ -6279,6 +6279,8 @@ static int mwl8k_probe(struct pci_dev *p | @@ -6280,6 +6280,8 @@ static int mwl8k_probe(struct pci_dev *p | ||||||
|   |   | ||||||
|  	priv->running_bsses = 0; |  	priv->running_bsses = 0; | ||||||
|   |   | ||||||
| @@ -9,7 +9,7 @@ | |||||||
|  	return rc; |  	return rc; | ||||||
|   |   | ||||||
|  err_stop_firmware: |  err_stop_firmware: | ||||||
| @@ -6312,8 +6314,6 @@ static void mwl8k_remove(struct pci_dev | @@ -6313,8 +6315,6 @@ static void mwl8k_remove(struct pci_dev | ||||||
|  		return; |  		return; | ||||||
|  	priv = hw->priv; |  	priv = hw->priv; | ||||||
|   |   | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| --- a/local-symbols | --- a/local-symbols | ||||||
| +++ b/local-symbols | +++ b/local-symbols | ||||||
| @@ -333,6 +333,7 @@ RT2X00_LIB_FIRMWARE= | @@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= | ||||||
|  RT2X00_LIB_CRYPTO= |  RT2X00_LIB_CRYPTO= | ||||||
|  RT2X00_LIB_LEDS= |  RT2X00_LIB_LEDS= | ||||||
|  RT2X00_LIB_DEBUGFS= |  RT2X00_LIB_DEBUGFS= | ||||||
|   | |||||||
| @@ -1,817 +0,0 @@ | |||||||
| From 8f392a72419c4b10e84e635e51bee24670975364 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Ping-Ke Shih <pkshih@realtek.com> |  | ||||||
| Date: Fri, 19 Feb 2021 13:26:07 +0800 |  | ||||||
| Subject: [PATCH] rtlwifi: 8821ae: upgrade PHY and RF parameters |  | ||||||
|  |  | ||||||
| New parameters with new format and its parser are updated by the |  | ||||||
| commit 84d26fda52e2 ("rtlwifi: Update 8821ae new phy parameters and its parser."), |  | ||||||
| but some parameters are missing. Use this commit to update to the novel |  | ||||||
| parameters that use new format. |  | ||||||
|  |  | ||||||
| Fixes: 84d26fda52e2 ("rtlwifi: Update 8821ae new phy parameters and its parser") |  | ||||||
| Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> |  | ||||||
| Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> |  | ||||||
| --- |  | ||||||
|  .../realtek/rtlwifi/rtl8821ae/table.c         | 500 +++++++++++++----- |  | ||||||
|  1 file changed, 370 insertions(+), 130 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c |  | ||||||
| +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c |  | ||||||
| @@ -249,7 +249,7 @@ u32 RTL8821AE_PHY_REG_ARRAY[] = { |  | ||||||
|  	0x824, 0x00030FE0, |  | ||||||
|  	0x828, 0x00000000, |  | ||||||
|  	0x82C, 0x002081DD, |  | ||||||
| -	0x830, 0x2AAA8E24, |  | ||||||
| +	0x830, 0x2AAAEEC8, |  | ||||||
|  	0x834, 0x0037A706, |  | ||||||
|  	0x838, 0x06489B44, |  | ||||||
|  	0x83C, 0x0000095B, |  | ||||||
| @@ -324,10 +324,10 @@ u32 RTL8821AE_PHY_REG_ARRAY[] = { |  | ||||||
|  	0x9D8, 0x00000000, |  | ||||||
|  	0x9DC, 0x00000000, |  | ||||||
|  	0x9E0, 0x00005D00, |  | ||||||
| -	0x9E4, 0x00000002, |  | ||||||
| +	0x9E4, 0x00000003, |  | ||||||
|  	0x9E8, 0x00000001, |  | ||||||
|  	0xA00, 0x00D047C8, |  | ||||||
| -	0xA04, 0x01FF000C, |  | ||||||
| +	0xA04, 0x01FF800C, |  | ||||||
|  	0xA08, 0x8C8A8300, |  | ||||||
|  	0xA0C, 0x2E68000F, |  | ||||||
|  	0xA10, 0x9500BB78, |  | ||||||
| @@ -1320,7 +1320,11 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x083, 0x00021800, |  | ||||||
|  		0x084, 0x00028000, |  | ||||||
|  		0x085, 0x00048000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x086, 0x0009483A, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x086, 0x00094838, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x087, 0x00044980, |  | ||||||
|  		0x088, 0x00048000, |  | ||||||
|  		0x089, 0x0000D480, |  | ||||||
| @@ -1409,36 +1413,32 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x03C, 0x000CA000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x0EF, 0x00001100, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0004ADF3, |  | ||||||
|  		0x034, 0x00049DF0, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0004ADF3, |  | ||||||
|  		0x034, 0x00049DF0, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| -		0x034, 0x0004ADF3, |  | ||||||
| -		0x034, 0x00049DF0, |  | ||||||
| -	0xFF0F0200, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0004ADF5, |  | ||||||
|  		0x034, 0x00049DF2, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0004A0F3, |  | ||||||
| +		0x034, 0x000490B1, |  | ||||||
| +		0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0004A0F3, |  | ||||||
|  		0x034, 0x000490B1, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0004ADF5, |  | ||||||
| +		0x034, 0x00049DF2, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0004ADF3, |  | ||||||
| +		0x034, 0x00049DF0, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x0004ADF7, |  | ||||||
|  		0x034, 0x00049DF3, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| -		0x034, 0x00048DED, |  | ||||||
| -		0x034, 0x00047DEA, |  | ||||||
| -		0x034, 0x00046DE7, |  | ||||||
| -		0x034, 0x00045CE9, |  | ||||||
| -		0x034, 0x00044CE6, |  | ||||||
| -		0x034, 0x000438C6, |  | ||||||
| -		0x034, 0x00042886, |  | ||||||
| -		0x034, 0x00041486, |  | ||||||
| -		0x034, 0x00040447, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00048DED, |  | ||||||
|  		0x034, 0x00047DEA, |  | ||||||
|  		0x034, 0x00046DE7, |  | ||||||
| @@ -1448,7 +1448,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00042886, |  | ||||||
|  		0x034, 0x00041486, |  | ||||||
|  		0x034, 0x00040447, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00048DED, |  | ||||||
|  		0x034, 0x00047DEA, |  | ||||||
|  		0x034, 0x00046DE7, |  | ||||||
| @@ -1458,7 +1458,17 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00042886, |  | ||||||
|  		0x034, 0x00041486, |  | ||||||
|  		0x034, 0x00040447, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x000480AE, |  | ||||||
| +		0x034, 0x000470AB, |  | ||||||
| +		0x034, 0x0004608B, |  | ||||||
| +		0x034, 0x00045069, |  | ||||||
| +		0x034, 0x00044048, |  | ||||||
| +		0x034, 0x00043045, |  | ||||||
| +		0x034, 0x00042026, |  | ||||||
| +		0x034, 0x00041023, |  | ||||||
| +		0x034, 0x00040002, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x000480AE, |  | ||||||
|  		0x034, 0x000470AB, |  | ||||||
|  		0x034, 0x0004608B, |  | ||||||
| @@ -1468,7 +1478,17 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00042026, |  | ||||||
|  		0x034, 0x00041023, |  | ||||||
|  		0x034, 0x00040002, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x00048DED, |  | ||||||
| +		0x034, 0x00047DEA, |  | ||||||
| +		0x034, 0x00046DE7, |  | ||||||
| +		0x034, 0x00045CE9, |  | ||||||
| +		0x034, 0x00044CE6, |  | ||||||
| +		0x034, 0x000438C6, |  | ||||||
| +		0x034, 0x00042886, |  | ||||||
| +		0x034, 0x00041486, |  | ||||||
| +		0x034, 0x00040447, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x00048DEF, |  | ||||||
|  		0x034, 0x00047DEC, |  | ||||||
|  		0x034, 0x00046DE9, |  | ||||||
| @@ -1478,38 +1498,36 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x0004248A, |  | ||||||
|  		0x034, 0x0004108D, |  | ||||||
|  		0x034, 0x0004008A, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0200, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0002ADF4, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0002A0F3, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0002A0F3, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0002ADF4, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x0002ADF7, |  | ||||||
| -	0xFF0F0200, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| -		0x034, 0x00029DF4, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00029DF4, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00029DF4, |  | ||||||
| -	0xFF0F0200, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00029DF1, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x000290F0, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x000290F0, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x00029DF1, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x00029DF4, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x00029DF2, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| -		0x034, 0x00028DF1, |  | ||||||
| -		0x034, 0x00027DEE, |  | ||||||
| -		0x034, 0x00026DEB, |  | ||||||
| -		0x034, 0x00025CEC, |  | ||||||
| -		0x034, 0x00024CE9, |  | ||||||
| -		0x034, 0x000238CA, |  | ||||||
| -		0x034, 0x00022889, |  | ||||||
| -		0x034, 0x00021489, |  | ||||||
| -		0x034, 0x0002044A, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00028DF1, |  | ||||||
|  		0x034, 0x00027DEE, |  | ||||||
|  		0x034, 0x00026DEB, |  | ||||||
| @@ -1519,7 +1537,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00022889, |  | ||||||
|  		0x034, 0x00021489, |  | ||||||
|  		0x034, 0x0002044A, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00028DF1, |  | ||||||
|  		0x034, 0x00027DEE, |  | ||||||
|  		0x034, 0x00026DEB, |  | ||||||
| @@ -1529,7 +1547,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00022889, |  | ||||||
|  		0x034, 0x00021489, |  | ||||||
|  		0x034, 0x0002044A, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x000280AF, |  | ||||||
|  		0x034, 0x000270AC, |  | ||||||
|  		0x034, 0x0002608B, |  | ||||||
| @@ -1539,7 +1557,27 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00022026, |  | ||||||
|  		0x034, 0x00021023, |  | ||||||
|  		0x034, 0x00020002, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x000280AF, |  | ||||||
| +		0x034, 0x000270AC, |  | ||||||
| +		0x034, 0x0002608B, |  | ||||||
| +		0x034, 0x00025069, |  | ||||||
| +		0x034, 0x00024048, |  | ||||||
| +		0x034, 0x00023045, |  | ||||||
| +		0x034, 0x00022026, |  | ||||||
| +		0x034, 0x00021023, |  | ||||||
| +		0x034, 0x00020002, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x00028DF1, |  | ||||||
| +		0x034, 0x00027DEE, |  | ||||||
| +		0x034, 0x00026DEB, |  | ||||||
| +		0x034, 0x00025CEC, |  | ||||||
| +		0x034, 0x00024CE9, |  | ||||||
| +		0x034, 0x000238CA, |  | ||||||
| +		0x034, 0x00022889, |  | ||||||
| +		0x034, 0x00021489, |  | ||||||
| +		0x034, 0x0002044A, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x00028DEE, |  | ||||||
|  		0x034, 0x00027DEB, |  | ||||||
|  		0x034, 0x00026CCD, |  | ||||||
| @@ -1549,27 +1587,24 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00022849, |  | ||||||
|  		0x034, 0x00021449, |  | ||||||
|  		0x034, 0x0002004D, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F02C0, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x8000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0000A0D7, |  | ||||||
| +		0x034, 0x000090D3, |  | ||||||
| +		0x034, 0x000080B1, |  | ||||||
| +		0x034, 0x000070AE, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0000A0D7, |  | ||||||
|  		0x034, 0x000090D3, |  | ||||||
|  		0x034, 0x000080B1, |  | ||||||
|  		0x034, 0x000070AE, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x0000ADF7, |  | ||||||
|  		0x034, 0x00009DF4, |  | ||||||
|  		0x034, 0x00008DF1, |  | ||||||
|  		0x034, 0x00007DEE, |  | ||||||
| -	0xFF0F02C0, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| -		0x034, 0x00006DEB, |  | ||||||
| -		0x034, 0x00005CEC, |  | ||||||
| -		0x034, 0x00004CE9, |  | ||||||
| -		0x034, 0x000038CA, |  | ||||||
| -		0x034, 0x00002889, |  | ||||||
| -		0x034, 0x00001489, |  | ||||||
| -		0x034, 0x0000044A, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00006DEB, |  | ||||||
|  		0x034, 0x00005CEC, |  | ||||||
|  		0x034, 0x00004CE9, |  | ||||||
| @@ -1577,7 +1612,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00002889, |  | ||||||
|  		0x034, 0x00001489, |  | ||||||
|  		0x034, 0x0000044A, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x00006DEB, |  | ||||||
|  		0x034, 0x00005CEC, |  | ||||||
|  		0x034, 0x00004CE9, |  | ||||||
| @@ -1585,7 +1620,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00002889, |  | ||||||
|  		0x034, 0x00001489, |  | ||||||
|  		0x034, 0x0000044A, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x034, 0x0000608D, |  | ||||||
|  		0x034, 0x0000506B, |  | ||||||
|  		0x034, 0x0000404A, |  | ||||||
| @@ -1593,7 +1628,23 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00002044, |  | ||||||
|  		0x034, 0x00001025, |  | ||||||
|  		0x034, 0x00000004, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x0000608D, |  | ||||||
| +		0x034, 0x0000506B, |  | ||||||
| +		0x034, 0x0000404A, |  | ||||||
| +		0x034, 0x00003047, |  | ||||||
| +		0x034, 0x00002044, |  | ||||||
| +		0x034, 0x00001025, |  | ||||||
| +		0x034, 0x00000004, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x034, 0x00006DEB, |  | ||||||
| +		0x034, 0x00005CEC, |  | ||||||
| +		0x034, 0x00004CE9, |  | ||||||
| +		0x034, 0x000038CA, |  | ||||||
| +		0x034, 0x00002889, |  | ||||||
| +		0x034, 0x00001489, |  | ||||||
| +		0x034, 0x0000044A, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x034, 0x00006DCD, |  | ||||||
|  		0x034, 0x00005CCD, |  | ||||||
|  		0x034, 0x00004CCA, |  | ||||||
| @@ -1601,11 +1652,11 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x034, 0x00002888, |  | ||||||
|  		0x034, 0x00001488, |  | ||||||
|  		0x034, 0x00000486, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x018, 0x0001712A, |  | ||||||
|  		0x0EF, 0x00000040, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x035, 0x00000187, |  | ||||||
|  		0x035, 0x00008187, |  | ||||||
|  		0x035, 0x00010187, |  | ||||||
| @@ -1615,7 +1666,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x035, 0x00040188, |  | ||||||
|  		0x035, 0x00048188, |  | ||||||
|  		0x035, 0x00050188, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x035, 0x00000187, |  | ||||||
|  		0x035, 0x00008187, |  | ||||||
|  		0x035, 0x00010187, |  | ||||||
| @@ -1625,7 +1676,37 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x035, 0x00040188, |  | ||||||
|  		0x035, 0x00048188, |  | ||||||
|  		0x035, 0x00050188, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x035, 0x00000128, |  | ||||||
| +		0x035, 0x00008128, |  | ||||||
| +		0x035, 0x00010128, |  | ||||||
| +		0x035, 0x000201C8, |  | ||||||
| +		0x035, 0x000281C8, |  | ||||||
| +		0x035, 0x000301C8, |  | ||||||
| +		0x035, 0x000401C8, |  | ||||||
| +		0x035, 0x000481C8, |  | ||||||
| +		0x035, 0x000501C8, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x035, 0x00000145, |  | ||||||
| +		0x035, 0x00008145, |  | ||||||
| +		0x035, 0x00010145, |  | ||||||
| +		0x035, 0x00020196, |  | ||||||
| +		0x035, 0x00028196, |  | ||||||
| +		0x035, 0x00030196, |  | ||||||
| +		0x035, 0x000401C7, |  | ||||||
| +		0x035, 0x000481C7, |  | ||||||
| +		0x035, 0x000501C7, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x035, 0x00000128, |  | ||||||
| +		0x035, 0x00008128, |  | ||||||
| +		0x035, 0x00010128, |  | ||||||
| +		0x035, 0x000201C8, |  | ||||||
| +		0x035, 0x000281C8, |  | ||||||
| +		0x035, 0x000301C8, |  | ||||||
| +		0x035, 0x000401C8, |  | ||||||
| +		0x035, 0x000481C8, |  | ||||||
| +		0x035, 0x000501C8, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x035, 0x00000187, |  | ||||||
|  		0x035, 0x00008187, |  | ||||||
|  		0x035, 0x00010187, |  | ||||||
| @@ -1635,7 +1716,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x035, 0x00040188, |  | ||||||
|  		0x035, 0x00048188, |  | ||||||
|  		0x035, 0x00050188, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x035, 0x00000145, |  | ||||||
|  		0x035, 0x00008145, |  | ||||||
|  		0x035, 0x00010145, |  | ||||||
| @@ -1645,11 +1726,11 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x035, 0x000401C7, |  | ||||||
|  		0x035, 0x000481C7, |  | ||||||
|  		0x035, 0x000501C7, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x018, 0x0001712A, |  | ||||||
|  		0x0EF, 0x00000010, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x036, 0x00085733, |  | ||||||
|  		0x036, 0x0008D733, |  | ||||||
|  		0x036, 0x00095733, |  | ||||||
| @@ -1662,7 +1743,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x036, 0x000CE4B4, |  | ||||||
|  		0x036, 0x000D64B4, |  | ||||||
|  		0x036, 0x000DE4B4, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x036, 0x00085733, |  | ||||||
|  		0x036, 0x0008D733, |  | ||||||
|  		0x036, 0x00095733, |  | ||||||
| @@ -1675,7 +1756,46 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x036, 0x000CE4B4, |  | ||||||
|  		0x036, 0x000D64B4, |  | ||||||
|  		0x036, 0x000DE4B4, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x036, 0x000063B5, |  | ||||||
| +		0x036, 0x0000E3B5, |  | ||||||
| +		0x036, 0x000163B5, |  | ||||||
| +		0x036, 0x0001E3B5, |  | ||||||
| +		0x036, 0x000263B5, |  | ||||||
| +		0x036, 0x0002E3B5, |  | ||||||
| +		0x036, 0x000363B5, |  | ||||||
| +		0x036, 0x0003E3B5, |  | ||||||
| +		0x036, 0x000463B5, |  | ||||||
| +		0x036, 0x0004E3B5, |  | ||||||
| +		0x036, 0x000563B5, |  | ||||||
| +		0x036, 0x0005E3B5, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x036, 0x000056B3, |  | ||||||
| +		0x036, 0x0000D6B3, |  | ||||||
| +		0x036, 0x000156B3, |  | ||||||
| +		0x036, 0x0001D6B3, |  | ||||||
| +		0x036, 0x00026634, |  | ||||||
| +		0x036, 0x0002E634, |  | ||||||
| +		0x036, 0x00036634, |  | ||||||
| +		0x036, 0x0003E634, |  | ||||||
| +		0x036, 0x000467B4, |  | ||||||
| +		0x036, 0x0004E7B4, |  | ||||||
| +		0x036, 0x000567B4, |  | ||||||
| +		0x036, 0x0005E7B4, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x036, 0x000063B5, |  | ||||||
| +		0x036, 0x0000E3B5, |  | ||||||
| +		0x036, 0x000163B5, |  | ||||||
| +		0x036, 0x0001E3B5, |  | ||||||
| +		0x036, 0x000263B5, |  | ||||||
| +		0x036, 0x0002E3B5, |  | ||||||
| +		0x036, 0x000363B5, |  | ||||||
| +		0x036, 0x0003E3B5, |  | ||||||
| +		0x036, 0x000463B5, |  | ||||||
| +		0x036, 0x0004E3B5, |  | ||||||
| +		0x036, 0x000563B5, |  | ||||||
| +		0x036, 0x0005E3B5, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x036, 0x00085733, |  | ||||||
|  		0x036, 0x0008D733, |  | ||||||
|  		0x036, 0x00095733, |  | ||||||
| @@ -1688,7 +1808,7 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x036, 0x000CE4B4, |  | ||||||
|  		0x036, 0x000D64B4, |  | ||||||
|  		0x036, 0x000DE4B4, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x036, 0x000056B3, |  | ||||||
|  		0x036, 0x0000D6B3, |  | ||||||
|  		0x036, 0x000156B3, |  | ||||||
| @@ -1701,103 +1821,162 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x036, 0x0004E7B4, |  | ||||||
|  		0x036, 0x000567B4, |  | ||||||
|  		0x036, 0x0005E7B4, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x0EF, 0x00000008, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x000001C8, |  | ||||||
|  		0x03C, 0x00000492, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x000001C8, |  | ||||||
|  		0x03C, 0x00000492, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x000001B6, |  | ||||||
| +		0x03C, 0x00000492, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x0000022A, |  | ||||||
| +		0x03C, 0x00000594, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x000001B6, |  | ||||||
| +		0x03C, 0x00000492, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x000001C8, |  | ||||||
|  		0x03C, 0x00000492, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x03C, 0x0000022A, |  | ||||||
|  		0x03C, 0x00000594, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x00000800, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x00000800, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x00000800, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x03C, 0x00000820, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x00000820, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x00000800, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x03C, 0x00000800, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x03C, 0x00000900, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x018, 0x0001712A, |  | ||||||
|  		0x0EF, 0x00000002, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x008, 0x0004E400, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x008, 0x0004E400, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x008, 0x00002000, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x008, 0x00002000, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x008, 0x00002000, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x008, 0x00002000, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x008, 0x0004E400, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x008, 0x00002000, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x0EF, 0x00000000, |  | ||||||
|  		0x0DF, 0x000000C0, |  | ||||||
| -		0x01F, 0x00040064, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +		0x01F, 0x00000064, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x058, 0x000A7284, |  | ||||||
|  		0x059, 0x000600EC, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x058, 0x000A7284, |  | ||||||
|  		0x059, 0x000600EC, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x058, 0x00081184, |  | ||||||
| +		0x059, 0x0006016C, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x058, 0x00081184, |  | ||||||
| +		0x059, 0x0006016C, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x058, 0x00081184, |  | ||||||
| +		0x059, 0x0006016C, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x058, 0x000A7284, |  | ||||||
|  		0x059, 0x000600EC, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x058, 0x00081184, |  | ||||||
|  		0x059, 0x0006016C, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x061, 0x000E8D73, |  | ||||||
|  		0x062, 0x00093FC5, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x061, 0x000E8D73, |  | ||||||
|  		0x062, 0x00093FC5, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x061, 0x000EFD83, |  | ||||||
| +		0x062, 0x00093FCC, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x061, 0x000EAD53, |  | ||||||
| +		0x062, 0x00093BC4, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x061, 0x000EFD83, |  | ||||||
| +		0x062, 0x00093FCC, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x061, 0x000E8D73, |  | ||||||
|  		0x062, 0x00093FC5, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x061, 0x000EAD53, |  | ||||||
|  		0x062, 0x00093BC4, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x063, 0x000110E9, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x063, 0x000110E9, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x063, 0x000110EB, |  | ||||||
| +	0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x063, 0x000110E9, |  | ||||||
| -	0xFF0F0200, 0xCDEF, |  | ||||||
| -		0x063, 0x000710E9, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x063, 0x000110E9, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x063, 0x000110EB, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x063, 0x000110E9, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x063, 0x000714E9, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0104, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x064, 0x0001C27C, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x064, 0x0001C27C, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x064, 0x0001C27C, |  | ||||||
| -	0xFF0F0204, 0xCDEF, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x064, 0x0001C67C, |  | ||||||
| +	0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x064, 0x0001C27C, |  | ||||||
| -	0xFF0F0404, 0xCDEF, |  | ||||||
| +	0x90000410,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x064, 0x0001C27C, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x064, 0x0001C67C, |  | ||||||
| -	0xFF0F0104, 0xDEAD, |  | ||||||
| -	0xFF0F0200, 0xABCD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
| +	0x80000111,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x065, 0x00091016, |  | ||||||
| +	0x90000110,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x065, 0x00091016, |  | ||||||
| +	0x90000210,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x065, 0x00093016, |  | ||||||
| -	0xFF0F02C0, 0xCDEF, |  | ||||||
| +		0x9000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x065, 0x00093015, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +		0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x065, 0x00093015, |  | ||||||
| +		0x90000200,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x065, 0x00093016, |  | ||||||
| +		0xA0000000,	0x00000000, |  | ||||||
|  		0x065, 0x00091016, |  | ||||||
| -	0xFF0F0200, 0xDEAD, |  | ||||||
| +		0xB0000000,	0x00000000, |  | ||||||
|  		0x018, 0x00000006, |  | ||||||
|  		0x0EF, 0x00002000, |  | ||||||
|  		0x03B, 0x0003824B, |  | ||||||
| @@ -1895,9 +2074,10 @@ u32 RTL8821AE_RADIOA_ARRAY[] = { |  | ||||||
|  		0x0B4, 0x0001214C, |  | ||||||
|  		0x0B7, 0x0003000C, |  | ||||||
|  		0x01C, 0x000539D2, |  | ||||||
| +		0x0C4, 0x000AFE00, |  | ||||||
|  		0x018, 0x0001F12A, |  | ||||||
| -		0x0FE, 0x00000000, |  | ||||||
| -		0x0FE, 0x00000000, |  | ||||||
| +		0xFFE, 0x00000000, |  | ||||||
| +		0xFFE, 0x00000000, |  | ||||||
|  		0x018, 0x0001712A, |  | ||||||
|   |  | ||||||
|  }; |  | ||||||
| @@ -2017,6 +2197,7 @@ u32 RTL8812AE_MAC_REG_ARRAY[] = { |  | ||||||
|  u32 RTL8812AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8812AE_MAC_REG_ARRAY); |  | ||||||
|   |  | ||||||
|  u32 RTL8821AE_MAC_REG_ARRAY[] = { |  | ||||||
| +		0x421, 0x0000000F, |  | ||||||
|  		0x428, 0x0000000A, |  | ||||||
|  		0x429, 0x00000010, |  | ||||||
|  		0x430, 0x00000000, |  | ||||||
| @@ -2485,7 +2666,7 @@ u32 RTL8821AE_AGC_TAB_ARRAY[] = { |  | ||||||
|  		0x81C, 0xA6360001, |  | ||||||
|  		0x81C, 0xA5380001, |  | ||||||
|  		0x81C, 0xA43A0001, |  | ||||||
| -		0x81C, 0xA33C0001, |  | ||||||
| +		0x81C, 0x683C0001, |  | ||||||
|  		0x81C, 0x673E0001, |  | ||||||
|  		0x81C, 0x66400001, |  | ||||||
|  		0x81C, 0x65420001, |  | ||||||
| @@ -2519,7 +2700,66 @@ u32 RTL8821AE_AGC_TAB_ARRAY[] = { |  | ||||||
|  		0x81C, 0x017A0001, |  | ||||||
|  		0x81C, 0x017C0001, |  | ||||||
|  		0x81C, 0x017E0001, |  | ||||||
| -	0xFF0F02C0, 0xABCD, |  | ||||||
| +	0x8000020c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
| +		0x81C, 0xFB000101, |  | ||||||
| +		0x81C, 0xFA020101, |  | ||||||
| +		0x81C, 0xF9040101, |  | ||||||
| +		0x81C, 0xF8060101, |  | ||||||
| +		0x81C, 0xF7080101, |  | ||||||
| +		0x81C, 0xF60A0101, |  | ||||||
| +		0x81C, 0xF50C0101, |  | ||||||
| +		0x81C, 0xF40E0101, |  | ||||||
| +		0x81C, 0xF3100101, |  | ||||||
| +		0x81C, 0xF2120101, |  | ||||||
| +		0x81C, 0xF1140101, |  | ||||||
| +		0x81C, 0xF0160101, |  | ||||||
| +		0x81C, 0xEF180101, |  | ||||||
| +		0x81C, 0xEE1A0101, |  | ||||||
| +		0x81C, 0xED1C0101, |  | ||||||
| +		0x81C, 0xEC1E0101, |  | ||||||
| +		0x81C, 0xEB200101, |  | ||||||
| +		0x81C, 0xEA220101, |  | ||||||
| +		0x81C, 0xE9240101, |  | ||||||
| +		0x81C, 0xE8260101, |  | ||||||
| +		0x81C, 0xE7280101, |  | ||||||
| +		0x81C, 0xE62A0101, |  | ||||||
| +		0x81C, 0xE52C0101, |  | ||||||
| +		0x81C, 0xE42E0101, |  | ||||||
| +		0x81C, 0xE3300101, |  | ||||||
| +		0x81C, 0xA5320101, |  | ||||||
| +		0x81C, 0xA4340101, |  | ||||||
| +		0x81C, 0xA3360101, |  | ||||||
| +		0x81C, 0x87380101, |  | ||||||
| +		0x81C, 0x863A0101, |  | ||||||
| +		0x81C, 0x853C0101, |  | ||||||
| +		0x81C, 0x843E0101, |  | ||||||
| +		0x81C, 0x69400101, |  | ||||||
| +		0x81C, 0x68420101, |  | ||||||
| +		0x81C, 0x67440101, |  | ||||||
| +		0x81C, 0x66460101, |  | ||||||
| +		0x81C, 0x49480101, |  | ||||||
| +		0x81C, 0x484A0101, |  | ||||||
| +		0x81C, 0x474C0101, |  | ||||||
| +		0x81C, 0x2A4E0101, |  | ||||||
| +		0x81C, 0x29500101, |  | ||||||
| +		0x81C, 0x28520101, |  | ||||||
| +		0x81C, 0x27540101, |  | ||||||
| +		0x81C, 0x26560101, |  | ||||||
| +		0x81C, 0x25580101, |  | ||||||
| +		0x81C, 0x245A0101, |  | ||||||
| +		0x81C, 0x235C0101, |  | ||||||
| +		0x81C, 0x055E0101, |  | ||||||
| +		0x81C, 0x04600101, |  | ||||||
| +		0x81C, 0x03620101, |  | ||||||
| +		0x81C, 0x02640101, |  | ||||||
| +		0x81C, 0x01660101, |  | ||||||
| +		0x81C, 0x01680101, |  | ||||||
| +		0x81C, 0x016A0101, |  | ||||||
| +		0x81C, 0x016C0101, |  | ||||||
| +		0x81C, 0x016E0101, |  | ||||||
| +		0x81C, 0x01700101, |  | ||||||
| +		0x81C, 0x01720101, |  | ||||||
| +	0x9000040c,	0x00000000,	0x40000000,	0x00000000, |  | ||||||
|  		0x81C, 0xFB000101, |  | ||||||
|  		0x81C, 0xFA020101, |  | ||||||
|  		0x81C, 0xF9040101, |  | ||||||
| @@ -2578,7 +2818,7 @@ u32 RTL8821AE_AGC_TAB_ARRAY[] = { |  | ||||||
|  		0x81C, 0x016E0101, |  | ||||||
|  		0x81C, 0x01700101, |  | ||||||
|  		0x81C, 0x01720101, |  | ||||||
| -	0xCDCDCDCD, 0xCDCD, |  | ||||||
| +	0xA0000000,	0x00000000, |  | ||||||
|  		0x81C, 0xFF000101, |  | ||||||
|  		0x81C, 0xFF020101, |  | ||||||
|  		0x81C, 0xFE040101, |  | ||||||
| @@ -2637,7 +2877,7 @@ u32 RTL8821AE_AGC_TAB_ARRAY[] = { |  | ||||||
|  		0x81C, 0x046E0101, |  | ||||||
|  		0x81C, 0x03700101, |  | ||||||
|  		0x81C, 0x02720101, |  | ||||||
| -	0xFF0F02C0, 0xDEAD, |  | ||||||
| +	0xB0000000,	0x00000000, |  | ||||||
|  		0x81C, 0x01740101, |  | ||||||
|  		0x81C, 0x01760101, |  | ||||||
|  		0x81C, 0x01780101, |  | ||||||
| @@ -379,7 +379,7 @@ | |||||||
|  #endif /* AES_GCM_H */ |  #endif /* AES_GCM_H */ | ||||||
| --- a/net/mac80211/wpa.c | --- a/net/mac80211/wpa.c | ||||||
| +++ b/net/mac80211/wpa.c | +++ b/net/mac80211/wpa.c | ||||||
| @@ -311,7 +311,8 @@ ieee80211_crypto_tkip_decrypt(struct iee | @@ -312,7 +312,8 @@ ieee80211_crypto_tkip_decrypt(struct iee | ||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -389,7 +389,7 @@ | |||||||
|  { |  { | ||||||
|  	__le16 mask_fc; |  	__le16 mask_fc; | ||||||
|  	int a4_included, mgmt; |  	int a4_included, mgmt; | ||||||
| @@ -341,14 +342,8 @@ static void ccmp_special_blocks(struct s | @@ -342,14 +343,8 @@ static void ccmp_special_blocks(struct s | ||||||
|  	else |  	else | ||||||
|  		qos_tid = 0; |  		qos_tid = 0; | ||||||
|   |   | ||||||
| @@ -406,7 +406,7 @@ | |||||||
|   |   | ||||||
|  	/* Nonce: Nonce Flags | A2 | PN |  	/* Nonce: Nonce Flags | A2 | PN | ||||||
|  	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) |  	 * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) | ||||||
| @@ -356,6 +351,8 @@ static void ccmp_special_blocks(struct s | @@ -357,6 +352,8 @@ static void ccmp_special_blocks(struct s | ||||||
|  	b_0[1] = qos_tid | (mgmt << 4); |  	b_0[1] = qos_tid | (mgmt << 4); | ||||||
|  	memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |  	memcpy(&b_0[2], hdr->addr2, ETH_ALEN); | ||||||
|  	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); |  	memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); | ||||||
| @@ -415,7 +415,7 @@ | |||||||
|   |   | ||||||
|  	/* AAD (extra authenticate-only data) / masked 802.11 header |  	/* AAD (extra authenticate-only data) / masked 802.11 header | ||||||
|  	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |  	 * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ | ||||||
| @@ -412,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee8 | @@ -413,7 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8 | ||||||
|  	u8 *pos; |  	u8 *pos; | ||||||
|  	u8 pn[6]; |  	u8 pn[6]; | ||||||
|  	u64 pn64; |  	u64 pn64; | ||||||
| @@ -424,7 +424,7 @@ | |||||||
|  	u8 b_0[AES_BLOCK_SIZE]; |  	u8 b_0[AES_BLOCK_SIZE]; | ||||||
|   |   | ||||||
|  	if (info->control.hw_key && |  	if (info->control.hw_key && | ||||||
| @@ -467,9 +464,11 @@ static int ccmp_encrypt_skb(struct ieee8 | @@ -468,9 +465,11 @@ static int ccmp_encrypt_skb(struct ieee8 | ||||||
|  		return 0; |  		return 0; | ||||||
|   |   | ||||||
|  	pos += IEEE80211_CCMP_HDR_LEN; |  	pos += IEEE80211_CCMP_HDR_LEN; | ||||||
| @@ -439,7 +439,7 @@ | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
| @@ -542,13 +541,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee | @@ -543,13 +542,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee | ||||||
|  			u8 aad[2 * AES_BLOCK_SIZE]; |  			u8 aad[2 * AES_BLOCK_SIZE]; | ||||||
|  			u8 b_0[AES_BLOCK_SIZE]; |  			u8 b_0[AES_BLOCK_SIZE]; | ||||||
|  			/* hardware didn't decrypt/verify MIC */ |  			/* hardware didn't decrypt/verify MIC */ | ||||||
| @@ -455,7 +455,7 @@ | |||||||
|  				return RX_DROP_UNUSABLE; |  				return RX_DROP_UNUSABLE; | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
| @@ -643,7 +642,7 @@ static int gcmp_encrypt_skb(struct ieee8 | @@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8 | ||||||
|  	u8 *pos; |  	u8 *pos; | ||||||
|  	u8 pn[6]; |  	u8 pn[6]; | ||||||
|  	u64 pn64; |  	u64 pn64; | ||||||
| @@ -464,7 +464,7 @@ | |||||||
|  	u8 j_0[AES_BLOCK_SIZE]; |  	u8 j_0[AES_BLOCK_SIZE]; | ||||||
|   |   | ||||||
|  	if (info->control.hw_key && |  	if (info->control.hw_key && | ||||||
| @@ -700,8 +699,10 @@ static int gcmp_encrypt_skb(struct ieee8 | @@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8 | ||||||
|   |   | ||||||
|  	pos += IEEE80211_GCMP_HDR_LEN; |  	pos += IEEE80211_GCMP_HDR_LEN; | ||||||
|  	gcmp_special_blocks(skb, pn, j_0, aad); |  	gcmp_special_blocks(skb, pn, j_0, aad); | ||||||
| @@ -477,7 +477,7 @@ | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  ieee80211_tx_result |  ieee80211_tx_result | ||||||
| @@ -1128,9 +1129,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct | @@ -1133,9 +1134,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct | ||||||
|  	struct ieee80211_key *key = tx->key; |  	struct ieee80211_key *key = tx->key; | ||||||
|  	struct ieee80211_mmie_16 *mmie; |  	struct ieee80211_mmie_16 *mmie; | ||||||
|  	struct ieee80211_hdr *hdr; |  	struct ieee80211_hdr *hdr; | ||||||
| @@ -489,7 +489,7 @@ | |||||||
|   |   | ||||||
|  	if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) |  	if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) | ||||||
|  		return TX_DROP; |  		return TX_DROP; | ||||||
| @@ -1176,7 +1177,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct | @@ -1181,7 +1182,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct | ||||||
|  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||||||
|  	struct ieee80211_key *key = rx->key; |  	struct ieee80211_key *key = rx->key; | ||||||
|  	struct ieee80211_mmie_16 *mmie; |  	struct ieee80211_mmie_16 *mmie; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
|  static int ieee80211_ifa6_changed(struct notifier_block *nb, |  static int ieee80211_ifa6_changed(struct notifier_block *nb, | ||||||
|  				  unsigned long data, void *arg) |  				  unsigned long data, void *arg) | ||||||
|  { |  { | ||||||
| @@ -1312,14 +1312,14 @@ int ieee80211_register_hw(struct ieee802 | @@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802 | ||||||
|   |   | ||||||
|  	rtnl_unlock(); |  	rtnl_unlock(); | ||||||
|   |   | ||||||
| @@ -35,7 +35,7 @@ | |||||||
|  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; |  	local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; | ||||||
|  	result = register_inet6addr_notifier(&local->ifa6_notifier); |  	result = register_inet6addr_notifier(&local->ifa6_notifier); | ||||||
|  	if (result) |  	if (result) | ||||||
| @@ -1328,13 +1328,13 @@ int ieee80211_register_hw(struct ieee802 | @@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802 | ||||||
|   |   | ||||||
|  	return 0; |  	return 0; | ||||||
|   |   | ||||||
| @@ -52,7 +52,7 @@ | |||||||
|   fail_ifa: |   fail_ifa: | ||||||
|  #endif |  #endif | ||||||
|  	wiphy_unregister(local->hw.wiphy); |  	wiphy_unregister(local->hw.wiphy); | ||||||
| @@ -1362,10 +1362,10 @@ void ieee80211_unregister_hw(struct ieee | @@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee | ||||||
|  	tasklet_kill(&local->tx_pending_tasklet); |  	tasklet_kill(&local->tx_pending_tasklet); | ||||||
|  	tasklet_kill(&local->tasklet); |  	tasklet_kill(&local->tasklet); | ||||||
|   |   | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|   * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame |   * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame | ||||||
| --- a/net/mac80211/mlme.c | --- a/net/mac80211/mlme.c | ||||||
| +++ b/net/mac80211/mlme.c | +++ b/net/mac80211/mlme.c | ||||||
| @@ -2729,7 +2729,7 @@ static void ieee80211_report_disconnect( | @@ -2734,7 +2734,7 @@ static void ieee80211_report_disconnect( | ||||||
|  	}; |  	}; | ||||||
|   |   | ||||||
|  	if (tx) |  	if (tx) | ||||||
| @@ -42,7 +42,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	else |  	else | ||||||
|  		cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); |  		cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); | ||||||
|   |   | ||||||
| @@ -4719,7 +4719,8 @@ void ieee80211_mgd_quiesce(struct ieee80 | @@ -4724,7 +4724,8 @@ void ieee80211_mgd_quiesce(struct ieee80 | ||||||
|  		if (ifmgd->auth_data) |  		if (ifmgd->auth_data) | ||||||
|  			ieee80211_destroy_auth_data(sdata, false); |  			ieee80211_destroy_auth_data(sdata, false); | ||||||
|  		cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |  		cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|   * @vif: &struct ieee80211_vif pointer from the add_interface callback. |   * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||||||
| --- a/net/mac80211/ieee80211_i.h | --- a/net/mac80211/ieee80211_i.h | ||||||
| +++ b/net/mac80211/ieee80211_i.h | +++ b/net/mac80211/ieee80211_i.h | ||||||
| @@ -461,7 +461,9 @@ struct ieee80211_if_managed { | @@ -450,7 +450,9 @@ struct ieee80211_if_managed { | ||||||
|  	unsigned long probe_timeout; |  	unsigned long probe_timeout; | ||||||
|  	int probe_send_count; |  	int probe_send_count; | ||||||
|  	bool nullfunc_failed; |  	bool nullfunc_failed; | ||||||
| @@ -47,7 +47,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	struct ieee80211_mgd_auth_data *auth_data; |  	struct ieee80211_mgd_auth_data *auth_data; | ||||||
| --- a/net/mac80211/mlme.c | --- a/net/mac80211/mlme.c | ||||||
| +++ b/net/mac80211/mlme.c | +++ b/net/mac80211/mlme.c | ||||||
| @@ -2720,7 +2720,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) | @@ -2725,7 +2725,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) | ||||||
|   |   | ||||||
|  static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata, |  static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata, | ||||||
|  					const u8 *buf, size_t len, bool tx, |  					const u8 *buf, size_t len, bool tx, | ||||||
| @@ -56,7 +56,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  { |  { | ||||||
|  	struct ieee80211_event event = { |  	struct ieee80211_event event = { | ||||||
|  		.type = MLME_EVENT, |  		.type = MLME_EVENT, | ||||||
| @@ -2729,7 +2729,7 @@ static void ieee80211_report_disconnect( | @@ -2734,7 +2734,7 @@ static void ieee80211_report_disconnect( | ||||||
|  	}; |  	}; | ||||||
|   |   | ||||||
|  	if (tx) |  	if (tx) | ||||||
| @@ -65,7 +65,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	else |  	else | ||||||
|  		cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); |  		cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); | ||||||
|   |   | ||||||
| @@ -2751,13 +2751,18 @@ static void __ieee80211_disconnect(struc | @@ -2756,13 +2756,18 @@ static void __ieee80211_disconnect(struc | ||||||
|   |   | ||||||
|  	tx = !sdata->csa_block_tx; |  	tx = !sdata->csa_block_tx; | ||||||
|   |   | ||||||
| @@ -89,7 +89,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  			       tx, frame_buf); |  			       tx, frame_buf); | ||||||
|  	mutex_lock(&local->mtx); |  	mutex_lock(&local->mtx); | ||||||
|  	sdata->vif.csa_active = false; |  	sdata->vif.csa_active = false; | ||||||
| @@ -2770,7 +2775,9 @@ static void __ieee80211_disconnect(struc | @@ -2775,7 +2780,9 @@ static void __ieee80211_disconnect(struc | ||||||
|  	mutex_unlock(&local->mtx); |  	mutex_unlock(&local->mtx); | ||||||
|   |   | ||||||
|  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx, |  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx, | ||||||
| @@ -100,7 +100,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|   |   | ||||||
|  	sdata_unlock(sdata); |  	sdata_unlock(sdata); | ||||||
|  } |  } | ||||||
| @@ -2789,6 +2796,13 @@ static void ieee80211_beacon_connection_ | @@ -2794,6 +2801,13 @@ static void ieee80211_beacon_connection_ | ||||||
|  		sdata_info(sdata, "Connection to AP %pM lost\n", |  		sdata_info(sdata, "Connection to AP %pM lost\n", | ||||||
|  			   ifmgd->bssid); |  			   ifmgd->bssid); | ||||||
|  		__ieee80211_disconnect(sdata); |  		__ieee80211_disconnect(sdata); | ||||||
| @@ -114,7 +114,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	} else { |  	} else { | ||||||
|  		ieee80211_mgd_probe_ap(sdata, true); |  		ieee80211_mgd_probe_ap(sdata, true); | ||||||
|  	} |  	} | ||||||
| @@ -2827,6 +2841,21 @@ void ieee80211_connection_loss(struct ie | @@ -2832,6 +2846,21 @@ void ieee80211_connection_loss(struct ie | ||||||
|  } |  } | ||||||
|  EXPORT_SYMBOL(ieee80211_connection_loss); |  EXPORT_SYMBOL(ieee80211_connection_loss); | ||||||
|   |   | ||||||
| @@ -136,7 +136,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|   |   | ||||||
|  static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, |  static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | ||||||
|  					bool assoc) |  					bool assoc) | ||||||
| @@ -3130,7 +3159,7 @@ static void ieee80211_rx_mgmt_deauth(str | @@ -3135,7 +3164,7 @@ static void ieee80211_rx_mgmt_deauth(str | ||||||
|  		ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |  		ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | ||||||
|   |   | ||||||
|  		ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, |  		ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, | ||||||
| @@ -145,7 +145,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  		return; |  		return; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -3179,7 +3208,8 @@ static void ieee80211_rx_mgmt_disassoc(s | @@ -3184,7 +3213,8 @@ static void ieee80211_rx_mgmt_disassoc(s | ||||||
|   |   | ||||||
|  	ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |  	ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | ||||||
|   |   | ||||||
| @@ -155,7 +155,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  static void ieee80211_get_rates(struct ieee80211_supported_band *sband, |  static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | ||||||
| @@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str | @@ -4204,7 +4234,8 @@ static void ieee80211_rx_mgmt_beacon(str | ||||||
|  				       true, deauth_buf); |  				       true, deauth_buf); | ||||||
|  		ieee80211_report_disconnect(sdata, deauth_buf, |  		ieee80211_report_disconnect(sdata, deauth_buf, | ||||||
|  					    sizeof(deauth_buf), true, |  					    sizeof(deauth_buf), true, | ||||||
| @@ -165,7 +165,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  		return; |  		return; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los | @@ -4349,7 +4380,7 @@ static void ieee80211_sta_connection_los | ||||||
|  			       tx, frame_buf); |  			       tx, frame_buf); | ||||||
|   |   | ||||||
|  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, |  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, | ||||||
| @@ -174,7 +174,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  } |  } | ||||||
|   |   | ||||||
|  static int ieee80211_auth(struct ieee80211_sub_if_data *sdata) |  static int ieee80211_auth(struct ieee80211_sub_if_data *sdata) | ||||||
| @@ -5434,7 +5465,8 @@ int ieee80211_mgd_auth(struct ieee80211_ | @@ -5439,7 +5470,8 @@ int ieee80211_mgd_auth(struct ieee80211_ | ||||||
|   |   | ||||||
|  		ieee80211_report_disconnect(sdata, frame_buf, |  		ieee80211_report_disconnect(sdata, frame_buf, | ||||||
|  					    sizeof(frame_buf), true, |  					    sizeof(frame_buf), true, | ||||||
| @@ -184,7 +184,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |  	sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | ||||||
| @@ -5506,7 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211 | @@ -5511,7 +5543,8 @@ int ieee80211_mgd_assoc(struct ieee80211 | ||||||
|   |   | ||||||
|  		ieee80211_report_disconnect(sdata, frame_buf, |  		ieee80211_report_disconnect(sdata, frame_buf, | ||||||
|  					    sizeof(frame_buf), true, |  					    sizeof(frame_buf), true, | ||||||
| @@ -194,7 +194,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	if (ifmgd->auth_data && !ifmgd->auth_data->done) { |  	if (ifmgd->auth_data && !ifmgd->auth_data->done) { | ||||||
| @@ -5805,7 +5838,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | @@ -5810,7 +5843,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | ||||||
|  		ieee80211_destroy_auth_data(sdata, false); |  		ieee80211_destroy_auth_data(sdata, false); | ||||||
|  		ieee80211_report_disconnect(sdata, frame_buf, |  		ieee80211_report_disconnect(sdata, frame_buf, | ||||||
|  					    sizeof(frame_buf), true, |  					    sizeof(frame_buf), true, | ||||||
| @@ -203,7 +203,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|   |   | ||||||
|  		return 0; |  		return 0; | ||||||
|  	} |  	} | ||||||
| @@ -5825,7 +5858,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | @@ -5830,7 +5863,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | ||||||
|  		ieee80211_destroy_assoc_data(sdata, false, true); |  		ieee80211_destroy_assoc_data(sdata, false, true); | ||||||
|  		ieee80211_report_disconnect(sdata, frame_buf, |  		ieee80211_report_disconnect(sdata, frame_buf, | ||||||
|  					    sizeof(frame_buf), true, |  					    sizeof(frame_buf), true, | ||||||
| @@ -212,7 +212,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  		return 0; |  		return 0; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -5840,7 +5873,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | @@ -5845,7 +5878,7 @@ int ieee80211_mgd_deauth(struct ieee8021 | ||||||
|  				       req->reason_code, tx, frame_buf); |  				       req->reason_code, tx, frame_buf); | ||||||
|  		ieee80211_report_disconnect(sdata, frame_buf, |  		ieee80211_report_disconnect(sdata, frame_buf, | ||||||
|  					    sizeof(frame_buf), true, |  					    sizeof(frame_buf), true, | ||||||
| @@ -221,7 +221,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  		return 0; |  		return 0; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -5873,7 +5906,7 @@ int ieee80211_mgd_disassoc(struct ieee80 | @@ -5878,7 +5911,7 @@ int ieee80211_mgd_disassoc(struct ieee80 | ||||||
|  			       frame_buf); |  			       frame_buf); | ||||||
|   |   | ||||||
|  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, |  	ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  static int fq_init(struct fq *fq, int flows_cnt) |  static int fq_init(struct fq *fq, int flows_cnt) | ||||||
| --- a/net/mac80211/ieee80211_i.h | --- a/net/mac80211/ieee80211_i.h | ||||||
| +++ b/net/mac80211/ieee80211_i.h | +++ b/net/mac80211/ieee80211_i.h | ||||||
| @@ -857,7 +857,6 @@ enum txq_info_flags { | @@ -846,7 +846,6 @@ enum txq_info_flags { | ||||||
|   */ |   */ | ||||||
|  struct txq_info { |  struct txq_info { | ||||||
|  	struct fq_tin tin; |  	struct fq_tin tin; | ||||||
|   | |||||||
| @@ -132,7 +132,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  #endif /* __MAC80211_DRIVER_OPS */ |  #endif /* __MAC80211_DRIVER_OPS */ | ||||||
| --- a/net/mac80211/iface.c | --- a/net/mac80211/iface.c | ||||||
| +++ b/net/mac80211/iface.c | +++ b/net/mac80211/iface.c | ||||||
| @@ -839,7 +839,7 @@ static const struct net_device_ops ieee8 | @@ -835,7 +835,7 @@ static const struct net_device_ops ieee8 | ||||||
|   |   | ||||||
|  }; |  }; | ||||||
|   |   | ||||||
| @@ -141,7 +141,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  { |  { | ||||||
|  	switch (iftype) { |  	switch (iftype) { | ||||||
|  	/* P2P GO and client are mapped to AP/STATION types */ |  	/* P2P GO and client are mapped to AP/STATION types */ | ||||||
| @@ -859,7 +859,7 @@ static bool ieee80211_set_sdata_offload_ | @@ -855,7 +855,7 @@ static bool ieee80211_set_sdata_offload_ | ||||||
|  	flags = sdata->vif.offload_flags; |  	flags = sdata->vif.offload_flags; | ||||||
|   |   | ||||||
|  	if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && |  	if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && | ||||||
| @@ -150,7 +150,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  		flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED; |  		flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED; | ||||||
|   |   | ||||||
|  		if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) && |  		if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) && | ||||||
| @@ -872,10 +872,21 @@ static bool ieee80211_set_sdata_offload_ | @@ -868,10 +868,21 @@ static bool ieee80211_set_sdata_offload_ | ||||||
|  		flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; |  		flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -172,7 +172,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	return true; |  	return true; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -893,7 +904,7 @@ static void ieee80211_set_vif_encap_ops( | @@ -889,7 +900,7 @@ static void ieee80211_set_vif_encap_ops( | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
|  	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || |  	if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || | ||||||
| @@ -183,7 +183,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; |  	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; | ||||||
| --- a/net/mac80211/rx.c | --- a/net/mac80211/rx.c | ||||||
| +++ b/net/mac80211/rx.c | +++ b/net/mac80211/rx.c | ||||||
| @@ -4114,7 +4114,9 @@ void ieee80211_check_fast_rx(struct sta_ | @@ -4198,7 +4198,9 @@ void ieee80211_check_fast_rx(struct sta_ | ||||||
|  		.vif_type = sdata->vif.type, |  		.vif_type = sdata->vif.type, | ||||||
|  		.control_port_protocol = sdata->control_port_protocol, |  		.control_port_protocol = sdata->control_port_protocol, | ||||||
|  	}, *old, *new = NULL; |  	}, *old, *new = NULL; | ||||||
| @@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|   |   | ||||||
|  	/* use sparse to check that we don't return without updating */ |  	/* use sparse to check that we don't return without updating */ | ||||||
|  	__acquire(check_fast_rx); |  	__acquire(check_fast_rx); | ||||||
| @@ -4227,6 +4229,17 @@ void ieee80211_check_fast_rx(struct sta_ | @@ -4311,6 +4313,17 @@ void ieee80211_check_fast_rx(struct sta_ | ||||||
|  	if (assign) |  	if (assign) | ||||||
|  		new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); |  		new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); | ||||||
|   |   | ||||||
| @@ -211,7 +211,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	spin_lock_bh(&sta->lock); |  	spin_lock_bh(&sta->lock); | ||||||
|  	old = rcu_dereference_protected(sta->fast_rx, true); |  	old = rcu_dereference_protected(sta->fast_rx, true); | ||||||
|  	rcu_assign_pointer(sta->fast_rx, new); |  	rcu_assign_pointer(sta->fast_rx, new); | ||||||
| @@ -4273,6 +4286,108 @@ void ieee80211_check_fast_rx_iface(struc | @@ -4357,6 +4370,108 @@ void ieee80211_check_fast_rx_iface(struc | ||||||
|  	mutex_unlock(&local->sta_mtx); |  	mutex_unlock(&local->sta_mtx); | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -320,7 +320,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, |  static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, | ||||||
|  				     struct ieee80211_fast_rx *fast_rx) |  				     struct ieee80211_fast_rx *fast_rx) | ||||||
|  { |  { | ||||||
| @@ -4293,9 +4408,6 @@ static bool ieee80211_invoke_fast_rx(str | @@ -4377,9 +4492,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||||
|  	} addrs __aligned(2); |  	} addrs __aligned(2); | ||||||
|  	struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; |  	struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; | ||||||
|   |   | ||||||
| @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write |  	/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write | ||||||
|  	 * to a common data structure; drivers can implement that per queue |  	 * to a common data structure; drivers can implement that per queue | ||||||
|  	 * but we don't have that information in mac80211 |  	 * but we don't have that information in mac80211 | ||||||
| @@ -4369,32 +4481,6 @@ static bool ieee80211_invoke_fast_rx(str | @@ -4453,32 +4565,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||||
|  	    pskb_trim(skb, skb->len - fast_rx->icv_len)) |  	    pskb_trim(skb, skb->len - fast_rx->icv_len)) | ||||||
|  		goto drop; |  		goto drop; | ||||||
|   |   | ||||||
| @@ -363,7 +363,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	if (rx->key && !ieee80211_has_protected(hdr->frame_control)) |  	if (rx->key && !ieee80211_has_protected(hdr->frame_control)) | ||||||
|  		goto drop; |  		goto drop; | ||||||
|   |   | ||||||
| @@ -4406,12 +4492,6 @@ static bool ieee80211_invoke_fast_rx(str | @@ -4490,12 +4576,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||||
|  		return true; |  		return true; | ||||||
|  	} |  	} | ||||||
|   |   | ||||||
| @@ -376,7 +376,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	/* do the header conversion - first grab the addresses */ |  	/* do the header conversion - first grab the addresses */ | ||||||
|  	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); |  	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); | ||||||
|  	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); |  	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); | ||||||
| @@ -4420,62 +4500,14 @@ static bool ieee80211_invoke_fast_rx(str | @@ -4504,62 +4584,14 @@ static bool ieee80211_invoke_fast_rx(str | ||||||
|  	/* push the addresses in front */ |  	/* push the addresses in front */ | ||||||
|  	memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); |  	memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); | ||||||
|   |   | ||||||
| @@ -443,7 +443,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  	stats->dropped++; |  	stats->dropped++; | ||||||
|  	return true; |  	return true; | ||||||
|  } |  } | ||||||
| @@ -4529,6 +4561,47 @@ static bool ieee80211_prepare_and_rx_han | @@ -4613,6 +4645,47 @@ static bool ieee80211_prepare_and_rx_han | ||||||
|  	return true; |  	return true; | ||||||
|  } |  } | ||||||
|   |   | ||||||
| @@ -491,7 +491,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | |||||||
|  /* |  /* | ||||||
|   * This is the actual Rx frames handler. as it belongs to Rx path it must |   * This is the actual Rx frames handler. as it belongs to Rx path it must | ||||||
|   * be called with rcu_read_lock protection. |   * be called with rcu_read_lock protection. | ||||||
| @@ -4766,15 +4839,20 @@ void ieee80211_rx_list(struct ieee80211_ | @@ -4850,15 +4923,20 @@ void ieee80211_rx_list(struct ieee80211_ | ||||||
|  	 * if it was previously present. |  	 * if it was previously present. | ||||||
|  	 * Also, frames with less than 16 bytes are dropped. |  	 * Also, frames with less than 16 bytes are dropped. | ||||||
|  	 */ |  	 */ | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | |||||||
|  |  | ||||||
| --- a/net/mac80211/ieee80211_i.h | --- a/net/mac80211/ieee80211_i.h | ||||||
| +++ b/net/mac80211/ieee80211_i.h | +++ b/net/mac80211/ieee80211_i.h | ||||||
| @@ -1600,13 +1600,8 @@ ieee80211_have_rx_timestamp(struct ieee8 | @@ -1587,13 +1587,8 @@ ieee80211_have_rx_timestamp(struct ieee8 | ||||||
|  { |  { | ||||||
|  	WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && |  	WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && | ||||||
|  		     status->flag & RX_FLAG_MACTIME_END); |  		     status->flag & RX_FLAG_MACTIME_END); | ||||||
|   | |||||||
| @@ -1,69 +0,0 @@ | |||||||
| From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Date: Tue, 11 May 2021 20:02:42 +0200 |  | ||||||
| Subject: [PATCH] mac80211: assure all fragments are encrypted |  | ||||||
|  |  | ||||||
| Do not mix plaintext and encrypted fragments in protected Wi-Fi |  | ||||||
| networks. This fixes CVE-2020-26147. |  | ||||||
|  |  | ||||||
| Previously, an attacker was able to first forward a legitimate encrypted |  | ||||||
| fragment towards a victim, followed by a plaintext fragment. The |  | ||||||
| encrypted and plaintext fragment would then be reassembled. For further |  | ||||||
| details see Section 6.3 and Appendix D in the paper "Fragment and Forge: |  | ||||||
| Breaking Wi-Fi Through Frame Aggregation and Fragmentation". |  | ||||||
|  |  | ||||||
| Because of this change there are now two equivalent conditions in the |  | ||||||
| code to determine if a received fragment requires sequential PNs, so we |  | ||||||
| also move this test to a separate function to make the code easier to |  | ||||||
| maintain. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2204,6 +2204,16 @@ ieee80211_reassemble_find(struct ieee802 |  | ||||||
|  	return NULL; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) |  | ||||||
| +{ |  | ||||||
| +	return rx->key && |  | ||||||
| +		(rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || |  | ||||||
| +		 rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || |  | ||||||
| +		 rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || |  | ||||||
| +		 rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && |  | ||||||
| +		ieee80211_has_protected(fc); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static ieee80211_rx_result debug_noinline |  | ||||||
|  ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |  | ||||||
|  { |  | ||||||
| @@ -2248,12 +2258,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  		/* This is the first fragment of a new frame. */ |  | ||||||
|  		entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |  | ||||||
|  						 rx->seqno_idx, &(rx->skb)); |  | ||||||
| -		if (rx->key && |  | ||||||
| -		    (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || |  | ||||||
| -		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || |  | ||||||
| -		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || |  | ||||||
| -		     rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && |  | ||||||
| -		    ieee80211_has_protected(fc)) { |  | ||||||
| +		if (requires_sequential_pn(rx, fc)) { |  | ||||||
|  			int queue = rx->security_idx; |  | ||||||
|   |  | ||||||
|  			/* Store CCMP/GCMP PN so that we can verify that the |  | ||||||
| @@ -2295,11 +2300,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  		u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; |  | ||||||
|  		int queue; |  | ||||||
|   |  | ||||||
| -		if (!rx->key || |  | ||||||
| -		    (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && |  | ||||||
| -		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && |  | ||||||
| -		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && |  | ||||||
| -		     rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) |  | ||||||
| +		if (!requires_sequential_pn(rx, fc)) |  | ||||||
|  			return RX_DROP_UNUSABLE; |  | ||||||
|  		memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
|  		for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { |  | ||||||
| @@ -1,87 +0,0 @@ | |||||||
| From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Date: Tue, 11 May 2021 20:02:43 +0200 |  | ||||||
| Subject: [PATCH] mac80211: prevent mixed key and fragment cache attacks |  | ||||||
|  |  | ||||||
| Simultaneously prevent mixed key attacks (CVE-2020-24587) and fragment |  | ||||||
| cache attacks (CVE-2020-24586). This is accomplished by assigning a |  | ||||||
| unique color to every key (per interface) and using this to track which |  | ||||||
| key was used to decrypt a fragment. When reassembling frames, it is |  | ||||||
| now checked whether all fragments were decrypted using the same key. |  | ||||||
|  |  | ||||||
| To assure that fragment cache attacks are also prevented, the ID that is |  | ||||||
| assigned to keys is unique even over (re)associations and (re)connects. |  | ||||||
| This means fragments separated by a (re)association or (re)connect will |  | ||||||
| not be reassembled. Because mac80211 now also prevents the reassembly of |  | ||||||
| mixed encrypted and plaintext fragments, all cache attacks are prevented. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/ieee80211_i.h |  | ||||||
| +++ b/net/mac80211/ieee80211_i.h |  | ||||||
| @@ -97,6 +97,7 @@ struct ieee80211_fragment_entry { |  | ||||||
|  	u8 rx_queue; |  | ||||||
|  	bool check_sequential_pn; /* needed for CCMP/GCMP */ |  | ||||||
|  	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |  | ||||||
| +	unsigned int key_color; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|   |  | ||||||
| --- a/net/mac80211/key.c |  | ||||||
| +++ b/net/mac80211/key.c |  | ||||||
| @@ -799,6 +799,7 @@ int ieee80211_key_link(struct ieee80211_ |  | ||||||
|  		       struct ieee80211_sub_if_data *sdata, |  | ||||||
|  		       struct sta_info *sta) |  | ||||||
|  { |  | ||||||
| +	static atomic_t key_color = ATOMIC_INIT(0); |  | ||||||
|  	struct ieee80211_key *old_key; |  | ||||||
|  	int idx = key->conf.keyidx; |  | ||||||
|  	bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; |  | ||||||
| @@ -850,6 +851,12 @@ int ieee80211_key_link(struct ieee80211_ |  | ||||||
|  	key->sdata = sdata; |  | ||||||
|  	key->sta = sta; |  | ||||||
|   |  | ||||||
| +	/* |  | ||||||
| +	 * Assign a unique ID to every key so we can easily prevent mixed |  | ||||||
| +	 * key and fragment cache attacks. |  | ||||||
| +	 */ |  | ||||||
| +	key->color = atomic_inc_return(&key_color); |  | ||||||
| + |  | ||||||
|  	increment_tailroom_need_count(sdata); |  | ||||||
|   |  | ||||||
|  	ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |  | ||||||
| --- a/net/mac80211/key.h |  | ||||||
| +++ b/net/mac80211/key.h |  | ||||||
| @@ -128,6 +128,8 @@ struct ieee80211_key { |  | ||||||
|  	} debugfs; |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +	unsigned int color; |  | ||||||
| + |  | ||||||
|  	/* |  | ||||||
|  	 * key config, must be last because it contains key |  | ||||||
|  	 * material as variable length member |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2265,6 +2265,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  			 * next fragment has a sequential PN value. |  | ||||||
|  			 */ |  | ||||||
|  			entry->check_sequential_pn = true; |  | ||||||
| +			entry->key_color = rx->key->color; |  | ||||||
|  			memcpy(entry->last_pn, |  | ||||||
|  			       rx->key->u.ccmp.rx_pn[queue], |  | ||||||
|  			       IEEE80211_CCMP_PN_LEN); |  | ||||||
| @@ -2302,6 +2303,11 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|   |  | ||||||
|  		if (!requires_sequential_pn(rx, fc)) |  | ||||||
|  			return RX_DROP_UNUSABLE; |  | ||||||
| + |  | ||||||
| +		/* Prevent mixed key and fragment cache attacks */ |  | ||||||
| +		if (entry->key_color != rx->key->color) |  | ||||||
| +			return RX_DROP_UNUSABLE; |  | ||||||
| + |  | ||||||
|  		memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
|  		for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { |  | ||||||
|  			pn[i]++; |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Date: Tue, 11 May 2021 20:02:44 +0200 |  | ||||||
| Subject: [PATCH] mac80211: properly handle A-MSDUs that start with an |  | ||||||
|  RFC 1042 header |  | ||||||
|  |  | ||||||
| Properly parse A-MSDUs whose first 6 bytes happen to equal a rfc1042 |  | ||||||
| header. This can occur in practice when the destination MAC address |  | ||||||
| equals AA:AA:03:00:00:00. More importantly, this simplifies the next |  | ||||||
| patch to mitigate A-MSDU injection attacks. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/include/net/cfg80211.h |  | ||||||
| +++ b/include/net/cfg80211.h |  | ||||||
| @@ -5637,7 +5637,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s |  | ||||||
|   */ |  | ||||||
|  int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, |  | ||||||
|  				  const u8 *addr, enum nl80211_iftype iftype, |  | ||||||
| -				  u8 data_offset); |  | ||||||
| +				  u8 data_offset, bool is_amsdu); |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
|   * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 |  | ||||||
| @@ -5649,7 +5649,7 @@ int ieee80211_data_to_8023_exthdr(struct |  | ||||||
|  static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, |  | ||||||
|  					 enum nl80211_iftype iftype) |  | ||||||
|  { |  | ||||||
| -	return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0); |  | ||||||
| +	return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0, false); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  /** |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2696,7 +2696,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ |  | ||||||
|  	if (ieee80211_data_to_8023_exthdr(skb, ðhdr, |  | ||||||
|  					  rx->sdata->vif.addr, |  | ||||||
|  					  rx->sdata->vif.type, |  | ||||||
| -					  data_offset)) |  | ||||||
| +					  data_offset, true)) |  | ||||||
|  		return RX_DROP_UNUSABLE; |  | ||||||
|   |  | ||||||
|  	ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, |  | ||||||
| --- a/net/wireless/util.c |  | ||||||
| +++ b/net/wireless/util.c |  | ||||||
| @@ -541,7 +541,7 @@ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen) |  | ||||||
|   |  | ||||||
|  int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, |  | ||||||
|  				  const u8 *addr, enum nl80211_iftype iftype, |  | ||||||
| -				  u8 data_offset) |  | ||||||
| +				  u8 data_offset, bool is_amsdu) |  | ||||||
|  { |  | ||||||
|  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |  | ||||||
|  	struct { |  | ||||||
| @@ -629,7 +629,7 @@ int ieee80211_data_to_8023_exthdr(struct |  | ||||||
|  	skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); |  | ||||||
|  	tmp.h_proto = payload.proto; |  | ||||||
|   |  | ||||||
| -	if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && |  | ||||||
| +	if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && |  | ||||||
|  		    tmp.h_proto != htons(ETH_P_AARP) && |  | ||||||
|  		    tmp.h_proto != htons(ETH_P_IPX)) || |  | ||||||
|  		   ether_addr_equal(payload.hdr, bridge_tunnel_header))) |  | ||||||
| @@ -1,40 +0,0 @@ | |||||||
| From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Date: Tue, 11 May 2021 20:02:45 +0200 |  | ||||||
| Subject: [PATCH] cfg80211: mitigate A-MSDU aggregation attacks |  | ||||||
|  |  | ||||||
| Mitigate A-MSDU injection attacks (CVE-2020-24588) by detecting if the |  | ||||||
| destination address of a subframe equals an RFC1042 (i.e., LLC/SNAP) |  | ||||||
| header, and if so dropping the complete A-MSDU frame. This mitigates |  | ||||||
| known attacks, although new (unknown) aggregation-based attacks may |  | ||||||
| remain possible. |  | ||||||
|  |  | ||||||
| This defense works because in A-MSDU aggregation injection attacks, a |  | ||||||
| normal encrypted Wi-Fi frame is turned into an A-MSDU frame. This means |  | ||||||
| the first 6 bytes of the first A-MSDU subframe correspond to an RFC1042 |  | ||||||
| header. In other words, the destination MAC address of the first A-MSDU |  | ||||||
| subframe contains the start of an RFC1042 header during an aggregation |  | ||||||
| attack. We can detect this and thereby prevent this specific attack. |  | ||||||
| For details, see Section 7.2 of "Fragment and Forge: Breaking Wi-Fi |  | ||||||
| Through Frame Aggregation and Fragmentation". |  | ||||||
|  |  | ||||||
| Note that for kernel 4.9 and above this patch depends on "mac80211: |  | ||||||
| properly handle A-MSDUs that start with a rfc1042 header". Otherwise |  | ||||||
| this patch has no impact and attacks will remain possible. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/wireless/util.c |  | ||||||
| +++ b/net/wireless/util.c |  | ||||||
| @@ -775,6 +775,9 @@ void ieee80211_amsdu_to_8023s(struct sk_ |  | ||||||
|  		remaining = skb->len - offset; |  | ||||||
|  		if (subframe_len > remaining) |  | ||||||
|  			goto purge; |  | ||||||
| +		/* mitigate A-MSDU aggregation injection attacks */ |  | ||||||
| +		if (ether_addr_equal(eth.h_dest, rfc1042_header)) |  | ||||||
| +			goto purge; |  | ||||||
|   |  | ||||||
|  		offset += sizeof(struct ethhdr); |  | ||||||
|  		last = remaining <= subframe_len + padding; |  | ||||||
| @@ -1,54 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Tue, 11 May 2021 20:02:46 +0200 |  | ||||||
| Subject: [PATCH] mac80211: drop A-MSDUs on old ciphers |  | ||||||
|  |  | ||||||
| With old ciphers (WEP and TKIP) we shouldn't be using A-MSDUs |  | ||||||
| since A-MSDUs are only supported if we know that they are, and |  | ||||||
| the only practical way for that is HT support which doesn't |  | ||||||
| support old ciphers. |  | ||||||
|  |  | ||||||
| However, we would normally accept them anyway. Since we check |  | ||||||
| the MMIC before deaggregating A-MSDUs, and the A-MSDU bit in |  | ||||||
| the QoS header is not protected in TKIP (or WEP), this enables |  | ||||||
| attacks similar to CVE-2020-24588. To prevent that, drop A-MSDUs |  | ||||||
| completely with old ciphers. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -6,7 +6,7 @@ |  | ||||||
|   * Copyright 2007-2010	Johannes Berg <johannes@sipsolutions.net> |  | ||||||
|   * Copyright 2013-2014  Intel Mobile Communications GmbH |  | ||||||
|   * Copyright(c) 2015 - 2017 Intel Deutschland GmbH |  | ||||||
| - * Copyright (C) 2018-2020 Intel Corporation |  | ||||||
| + * Copyright (C) 2018-2021 Intel Corporation |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  #include <linux/jiffies.h> |  | ||||||
| @@ -2753,6 +2753,23 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx |  | ||||||
|  	if (is_multicast_ether_addr(hdr->addr1)) |  | ||||||
|  		return RX_DROP_UNUSABLE; |  | ||||||
|   |  | ||||||
| +	if (rx->key) { |  | ||||||
| +		/* |  | ||||||
| +		 * We should not receive A-MSDUs on pre-HT connections, |  | ||||||
| +		 * and HT connections cannot use old ciphers. Thus drop |  | ||||||
| +		 * them, as in those cases we couldn't even have SPP |  | ||||||
| +		 * A-MSDUs or such. |  | ||||||
| +		 */ |  | ||||||
| +		switch (rx->key->conf.cipher) { |  | ||||||
| +		case WLAN_CIPHER_SUITE_WEP40: |  | ||||||
| +		case WLAN_CIPHER_SUITE_WEP104: |  | ||||||
| +		case WLAN_CIPHER_SUITE_TKIP: |  | ||||||
| +			return RX_DROP_UNUSABLE; |  | ||||||
| +		default: |  | ||||||
| +			break; |  | ||||||
| +		} |  | ||||||
| +	} |  | ||||||
| + |  | ||||||
|  	return __ieee80211_rx_h_amsdu(rx, 0); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -1,313 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Tue, 11 May 2021 20:02:47 +0200 |  | ||||||
| Subject: [PATCH] mac80211: add fragment cache to sta_info |  | ||||||
|  |  | ||||||
| Prior patches protected against fragmentation cache attacks |  | ||||||
| by coloring keys, but this shows that it can lead to issues |  | ||||||
| when multiple stations use the same sequence number. Add a |  | ||||||
| fragment cache to struct sta_info (in addition to the one in |  | ||||||
| the interface) to separate fragments for different stations |  | ||||||
| properly. |  | ||||||
|  |  | ||||||
| This then automatically clear most of the fragment cache when a |  | ||||||
| station disconnects (or reassociates) from an AP, or when client |  | ||||||
| interfaces disconnect from the network, etc. |  | ||||||
|  |  | ||||||
| On the way, also fix the comment there since this brings us in line |  | ||||||
| with the recommendation in 802.11-2016 ("An AP should support ..."). |  | ||||||
| Additionally, remove a useless condition (since there's no problem |  | ||||||
| purging an already empty list). |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/ieee80211_i.h |  | ||||||
| +++ b/net/mac80211/ieee80211_i.h |  | ||||||
| @@ -50,12 +50,6 @@ struct ieee80211_local; |  | ||||||
|  #define IEEE80211_ENCRYPT_HEADROOM 8 |  | ||||||
|  #define IEEE80211_ENCRYPT_TAILROOM 18 |  | ||||||
|   |  | ||||||
| -/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent |  | ||||||
| - * reception of at least three fragmented frames. This limit can be increased |  | ||||||
| - * by changing this define, at the cost of slower frame reassembly and |  | ||||||
| - * increased memory use (about 2 kB of RAM per entry). */ |  | ||||||
| -#define IEEE80211_FRAGMENT_MAX 4 |  | ||||||
| - |  | ||||||
|  /* power level hasn't been configured (or set to automatic) */ |  | ||||||
|  #define IEEE80211_UNSET_POWER_LEVEL	INT_MIN |  | ||||||
|   |  | ||||||
| @@ -88,19 +82,6 @@ extern const u8 ieee80211_ac_to_qos_mask |  | ||||||
|   |  | ||||||
|  #define IEEE80211_MAX_NAN_INSTANCE_ID 255 |  | ||||||
|   |  | ||||||
| -struct ieee80211_fragment_entry { |  | ||||||
| -	struct sk_buff_head skb_list; |  | ||||||
| -	unsigned long first_frag_time; |  | ||||||
| -	u16 seq; |  | ||||||
| -	u16 extra_len; |  | ||||||
| -	u16 last_frag; |  | ||||||
| -	u8 rx_queue; |  | ||||||
| -	bool check_sequential_pn; /* needed for CCMP/GCMP */ |  | ||||||
| -	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |  | ||||||
| -	unsigned int key_color; |  | ||||||
| -}; |  | ||||||
| - |  | ||||||
| - |  | ||||||
|  struct ieee80211_bss { |  | ||||||
|  	u32 device_ts_beacon, device_ts_presp; |  | ||||||
|   |  | ||||||
| @@ -912,9 +893,7 @@ struct ieee80211_sub_if_data { |  | ||||||
|   |  | ||||||
|  	char name[IFNAMSIZ]; |  | ||||||
|   |  | ||||||
| -	/* Fragment table for host-based reassembly */ |  | ||||||
| -	struct ieee80211_fragment_entry	fragments[IEEE80211_FRAGMENT_MAX]; |  | ||||||
| -	unsigned int fragment_next; |  | ||||||
| +	struct ieee80211_fragment_cache frags; |  | ||||||
|   |  | ||||||
|  	/* TID bitmap for NoAck policy */ |  | ||||||
|  	u16 noack_map; |  | ||||||
| @@ -2329,4 +2308,7 @@ u32 ieee80211_calc_expected_tx_airtime(s |  | ||||||
|  #define debug_noinline |  | ||||||
|  #endif |  | ||||||
|   |  | ||||||
| +void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache); |  | ||||||
| +void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache); |  | ||||||
| + |  | ||||||
|  #endif /* IEEE80211_I_H */ |  | ||||||
| --- a/net/mac80211/iface.c |  | ||||||
| +++ b/net/mac80211/iface.c |  | ||||||
| @@ -8,7 +8,7 @@ |  | ||||||
|   * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |  | ||||||
|   * Copyright 2013-2014  Intel Mobile Communications GmbH |  | ||||||
|   * Copyright (c) 2016        Intel Deutschland GmbH |  | ||||||
| - * Copyright (C) 2018-2020 Intel Corporation |  | ||||||
| + * Copyright (C) 2018-2021 Intel Corporation |  | ||||||
|   */ |  | ||||||
|  #include <linux/slab.h> |  | ||||||
|  #include <linux/kernel.h> |  | ||||||
| @@ -679,16 +679,12 @@ static void ieee80211_set_multicast_list |  | ||||||
|   */ |  | ||||||
|  static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) |  | ||||||
|  { |  | ||||||
| -	int i; |  | ||||||
| - |  | ||||||
|  	/* free extra data */ |  | ||||||
|  	ieee80211_free_keys(sdata, false); |  | ||||||
|   |  | ||||||
|  	ieee80211_debugfs_remove_netdev(sdata); |  | ||||||
|   |  | ||||||
| -	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |  | ||||||
| -		__skb_queue_purge(&sdata->fragments[i].skb_list); |  | ||||||
| -	sdata->fragment_next = 0; |  | ||||||
| +	ieee80211_destroy_frag_cache(&sdata->frags); |  | ||||||
|   |  | ||||||
|  	if (ieee80211_vif_is_mesh(&sdata->vif)) |  | ||||||
|  		ieee80211_mesh_teardown_sdata(sdata); |  | ||||||
| @@ -2038,8 +2034,7 @@ int ieee80211_if_add(struct ieee80211_lo |  | ||||||
|  	sdata->wdev.wiphy = local->hw.wiphy; |  | ||||||
|  	sdata->local = local; |  | ||||||
|   |  | ||||||
| -	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |  | ||||||
| -		skb_queue_head_init(&sdata->fragments[i].skb_list); |  | ||||||
| +	ieee80211_init_frag_cache(&sdata->frags); |  | ||||||
|   |  | ||||||
|  	INIT_LIST_HEAD(&sdata->key_list); |  | ||||||
|   |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2133,19 +2133,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_ |  | ||||||
|  	return result; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| +void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache) |  | ||||||
| +{ |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < ARRAY_SIZE(cache->entries); i++) |  | ||||||
| +		skb_queue_head_init(&cache->entries[i].skb_list); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache) |  | ||||||
| +{ |  | ||||||
| +	int i; |  | ||||||
| + |  | ||||||
| +	for (i = 0; i < ARRAY_SIZE(cache->entries); i++) |  | ||||||
| +		__skb_queue_purge(&cache->entries[i].skb_list); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static inline struct ieee80211_fragment_entry * |  | ||||||
| -ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, |  | ||||||
| +ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache, |  | ||||||
|  			 unsigned int frag, unsigned int seq, int rx_queue, |  | ||||||
|  			 struct sk_buff **skb) |  | ||||||
|  { |  | ||||||
|  	struct ieee80211_fragment_entry *entry; |  | ||||||
|   |  | ||||||
| -	entry = &sdata->fragments[sdata->fragment_next++]; |  | ||||||
| -	if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |  | ||||||
| -		sdata->fragment_next = 0; |  | ||||||
| +	entry = &cache->entries[cache->next++]; |  | ||||||
| +	if (cache->next >= IEEE80211_FRAGMENT_MAX) |  | ||||||
| +		cache->next = 0; |  | ||||||
|   |  | ||||||
| -	if (!skb_queue_empty(&entry->skb_list)) |  | ||||||
| -		__skb_queue_purge(&entry->skb_list); |  | ||||||
| +	__skb_queue_purge(&entry->skb_list); |  | ||||||
|   |  | ||||||
|  	__skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ |  | ||||||
|  	*skb = NULL; |  | ||||||
| @@ -2160,14 +2175,14 @@ ieee80211_reassemble_add(struct ieee8021 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static inline struct ieee80211_fragment_entry * |  | ||||||
| -ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, |  | ||||||
| +ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache, |  | ||||||
|  			  unsigned int frag, unsigned int seq, |  | ||||||
|  			  int rx_queue, struct ieee80211_hdr *hdr) |  | ||||||
|  { |  | ||||||
|  	struct ieee80211_fragment_entry *entry; |  | ||||||
|  	int i, idx; |  | ||||||
|   |  | ||||||
| -	idx = sdata->fragment_next; |  | ||||||
| +	idx = cache->next; |  | ||||||
|  	for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { |  | ||||||
|  		struct ieee80211_hdr *f_hdr; |  | ||||||
|  		struct sk_buff *f_skb; |  | ||||||
| @@ -2176,7 +2191,7 @@ ieee80211_reassemble_find(struct ieee802 |  | ||||||
|  		if (idx < 0) |  | ||||||
|  			idx = IEEE80211_FRAGMENT_MAX - 1; |  | ||||||
|   |  | ||||||
| -		entry = &sdata->fragments[idx]; |  | ||||||
| +		entry = &cache->entries[idx]; |  | ||||||
|  		if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || |  | ||||||
|  		    entry->rx_queue != rx_queue || |  | ||||||
|  		    entry->last_frag + 1 != frag) |  | ||||||
| @@ -2217,6 +2232,7 @@ static bool requires_sequential_pn(struc |  | ||||||
|  static ieee80211_rx_result debug_noinline |  | ||||||
|  ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |  | ||||||
|  { |  | ||||||
| +	struct ieee80211_fragment_cache *cache = &rx->sdata->frags; |  | ||||||
|  	struct ieee80211_hdr *hdr; |  | ||||||
|  	u16 sc; |  | ||||||
|  	__le16 fc; |  | ||||||
| @@ -2238,6 +2254,9 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  		goto out_no_led; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| +	if (rx->sta) |  | ||||||
| +		cache = &rx->sta->frags; |  | ||||||
| + |  | ||||||
|  	if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) |  | ||||||
|  		goto out; |  | ||||||
|   |  | ||||||
| @@ -2256,7 +2275,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|   |  | ||||||
|  	if (frag == 0) { |  | ||||||
|  		/* This is the first fragment of a new frame. */ |  | ||||||
| -		entry = ieee80211_reassemble_add(rx->sdata, frag, seq, |  | ||||||
| +		entry = ieee80211_reassemble_add(cache, frag, seq, |  | ||||||
|  						 rx->seqno_idx, &(rx->skb)); |  | ||||||
|  		if (requires_sequential_pn(rx, fc)) { |  | ||||||
|  			int queue = rx->security_idx; |  | ||||||
| @@ -2284,7 +2303,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  	/* This is a fragment for a frame that should already be pending in |  | ||||||
|  	 * fragment cache. Add this fragment to the end of the pending entry. |  | ||||||
|  	 */ |  | ||||||
| -	entry = ieee80211_reassemble_find(rx->sdata, frag, seq, |  | ||||||
| +	entry = ieee80211_reassemble_find(cache, frag, seq, |  | ||||||
|  					  rx->seqno_idx, hdr); |  | ||||||
|  	if (!entry) { |  | ||||||
|  		I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |  | ||||||
| --- a/net/mac80211/sta_info.c |  | ||||||
| +++ b/net/mac80211/sta_info.c |  | ||||||
| @@ -4,7 +4,7 @@ |  | ||||||
|   * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz> |  | ||||||
|   * Copyright 2013-2014  Intel Mobile Communications GmbH |  | ||||||
|   * Copyright (C) 2015 - 2017 Intel Deutschland GmbH |  | ||||||
| - * Copyright (C) 2018-2020 Intel Corporation |  | ||||||
| + * Copyright (C) 2018-2021 Intel Corporation |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  #include <linux/module.h> |  | ||||||
| @@ -393,6 +393,8 @@ struct sta_info *sta_info_alloc(struct i |  | ||||||
|   |  | ||||||
|  	u64_stats_init(&sta->rx_stats.syncp); |  | ||||||
|   |  | ||||||
| +	ieee80211_init_frag_cache(&sta->frags); |  | ||||||
| + |  | ||||||
|  	sta->sta_state = IEEE80211_STA_NONE; |  | ||||||
|   |  | ||||||
|  	/* Mark TID as unreserved */ |  | ||||||
| @@ -1103,6 +1105,8 @@ static void __sta_info_destroy_part2(str |  | ||||||
|   |  | ||||||
|  	ieee80211_sta_debugfs_remove(sta); |  | ||||||
|   |  | ||||||
| +	ieee80211_destroy_frag_cache(&sta->frags); |  | ||||||
| + |  | ||||||
|  	cleanup_single_sta(sta); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| --- a/net/mac80211/sta_info.h |  | ||||||
| +++ b/net/mac80211/sta_info.h |  | ||||||
| @@ -3,7 +3,7 @@ |  | ||||||
|   * Copyright 2002-2005, Devicescape Software, Inc. |  | ||||||
|   * Copyright 2013-2014  Intel Mobile Communications GmbH |  | ||||||
|   * Copyright(c) 2015-2017 Intel Deutschland GmbH |  | ||||||
| - * Copyright(c) 2020 Intel Corporation |  | ||||||
| + * Copyright(c) 2020-2021 Intel Corporation |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  #ifndef STA_INFO_H |  | ||||||
| @@ -439,6 +439,33 @@ struct ieee80211_sta_rx_stats { |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
| + * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent |  | ||||||
| + * reception of at least one MSDU per access category per associated STA" |  | ||||||
| + * on APs, or "at least one MSDU per access category" on other interface types. |  | ||||||
| + * |  | ||||||
| + * This limit can be increased by changing this define, at the cost of slower |  | ||||||
| + * frame reassembly and increased memory use while fragments are pending. |  | ||||||
| + */ |  | ||||||
| +#define IEEE80211_FRAGMENT_MAX 4 |  | ||||||
| + |  | ||||||
| +struct ieee80211_fragment_entry { |  | ||||||
| +	struct sk_buff_head skb_list; |  | ||||||
| +	unsigned long first_frag_time; |  | ||||||
| +	u16 seq; |  | ||||||
| +	u16 extra_len; |  | ||||||
| +	u16 last_frag; |  | ||||||
| +	u8 rx_queue; |  | ||||||
| +	bool check_sequential_pn; /* needed for CCMP/GCMP */ |  | ||||||
| +	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |  | ||||||
| +	unsigned int key_color; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +struct ieee80211_fragment_cache { |  | ||||||
| +	struct ieee80211_fragment_entry	entries[IEEE80211_FRAGMENT_MAX]; |  | ||||||
| +	unsigned int next; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/* |  | ||||||
|   * The bandwidth threshold below which the per-station CoDel parameters will be |  | ||||||
|   * scaled to be more lenient (to prevent starvation of slow stations). This |  | ||||||
|   * value will be scaled by the number of active stations when it is being |  | ||||||
| @@ -531,6 +558,7 @@ struct ieee80211_sta_rx_stats { |  | ||||||
|   * @status_stats.last_ack_signal: last ACK signal |  | ||||||
|   * @status_stats.ack_signal_filled: last ACK signal validity |  | ||||||
|   * @status_stats.avg_ack_signal: average ACK signal |  | ||||||
| + * @frags: fragment cache |  | ||||||
|   */ |  | ||||||
|  struct sta_info { |  | ||||||
|  	/* General information, mostly static */ |  | ||||||
| @@ -639,6 +667,8 @@ struct sta_info { |  | ||||||
|   |  | ||||||
|  	struct cfg80211_chan_def tdls_chandef; |  | ||||||
|   |  | ||||||
| +	struct ieee80211_fragment_cache frags; |  | ||||||
| + |  | ||||||
|  	/* keep last! */ |  | ||||||
|  	struct ieee80211_sta sta; |  | ||||||
|  }; |  | ||||||
| @@ -1,109 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Tue, 11 May 2021 20:02:48 +0200 |  | ||||||
| Subject: [PATCH] mac80211: check defrag PN against current frame |  | ||||||
|  |  | ||||||
| As pointed out by Mathy Vanhoef, we implement the RX PN check |  | ||||||
| on fragmented frames incorrectly - we check against the last |  | ||||||
| received PN prior to the new frame, rather than to the one in |  | ||||||
| this frame itself. |  | ||||||
|  |  | ||||||
| Prior patches addressed the security issue here, but in order |  | ||||||
| to be able to reason better about the code, fix it to really |  | ||||||
| compare against the current frame's PN, not the last stored |  | ||||||
| one. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/ieee80211_i.h |  | ||||||
| +++ b/net/mac80211/ieee80211_i.h |  | ||||||
| @@ -227,8 +227,15 @@ struct ieee80211_rx_data { |  | ||||||
|  	 */ |  | ||||||
|  	int security_idx; |  | ||||||
|   |  | ||||||
| -	u32 tkip_iv32; |  | ||||||
| -	u16 tkip_iv16; |  | ||||||
| +	union { |  | ||||||
| +		struct { |  | ||||||
| +			u32 iv32; |  | ||||||
| +			u16 iv16; |  | ||||||
| +		} tkip; |  | ||||||
| +		struct { |  | ||||||
| +			u8 pn[IEEE80211_CCMP_PN_LEN]; |  | ||||||
| +		} ccm_gcm; |  | ||||||
| +	}; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
|  struct ieee80211_csa_settings { |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2318,7 +2318,6 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  	if (entry->check_sequential_pn) { |  | ||||||
|  		int i; |  | ||||||
|  		u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; |  | ||||||
| -		int queue; |  | ||||||
|   |  | ||||||
|  		if (!requires_sequential_pn(rx, fc)) |  | ||||||
|  			return RX_DROP_UNUSABLE; |  | ||||||
| @@ -2333,8 +2332,8 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  			if (pn[i]) |  | ||||||
|  				break; |  | ||||||
|  		} |  | ||||||
| -		queue = rx->security_idx; |  | ||||||
| -		rpn = rx->key->u.ccmp.rx_pn[queue]; |  | ||||||
| + |  | ||||||
| +		rpn = rx->ccm_gcm.pn; |  | ||||||
|  		if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) |  | ||||||
|  			return RX_DROP_UNUSABLE; |  | ||||||
|  		memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
| --- a/net/mac80211/wpa.c |  | ||||||
| +++ b/net/mac80211/wpa.c |  | ||||||
| @@ -3,6 +3,7 @@ |  | ||||||
|   * Copyright 2002-2004, Instant802 Networks, Inc. |  | ||||||
|   * Copyright 2008, Jouni Malinen <j@w1.fi> |  | ||||||
|   * Copyright (C) 2016-2017 Intel Deutschland GmbH |  | ||||||
| + * Copyright (C) 2020-2021 Intel Corporation |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
|  #include <linux/netdevice.h> |  | ||||||
| @@ -167,8 +168,8 @@ ieee80211_rx_h_michael_mic_verify(struct |  | ||||||
|   |  | ||||||
|  update_iv: |  | ||||||
|  	/* update IV in key information to be able to detect replays */ |  | ||||||
| -	rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; |  | ||||||
| -	rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; |  | ||||||
| +	rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32; |  | ||||||
| +	rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16; |  | ||||||
|   |  | ||||||
|  	return RX_CONTINUE; |  | ||||||
|   |  | ||||||
| @@ -294,8 +295,8 @@ ieee80211_crypto_tkip_decrypt(struct iee |  | ||||||
|  					  key, skb->data + hdrlen, |  | ||||||
|  					  skb->len - hdrlen, rx->sta->sta.addr, |  | ||||||
|  					  hdr->addr1, hwaccel, rx->security_idx, |  | ||||||
| -					  &rx->tkip_iv32, |  | ||||||
| -					  &rx->tkip_iv16); |  | ||||||
| +					  &rx->tkip.iv32, |  | ||||||
| +					  &rx->tkip.iv16); |  | ||||||
|  	if (res != TKIP_DECRYPT_OK) |  | ||||||
|  		return RX_DROP_UNUSABLE; |  | ||||||
|   |  | ||||||
| @@ -552,6 +553,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
| +		if (unlikely(ieee80211_is_frag(hdr))) |  | ||||||
| +			memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Remove CCMP header and MIC */ |  | ||||||
| @@ -782,6 +785,8 @@ ieee80211_crypto_gcmp_decrypt(struct iee |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); |  | ||||||
| +		if (unlikely(ieee80211_is_frag(hdr))) |  | ||||||
| +			memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* Remove GCMP header and MIC */ |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Tue, 11 May 2021 20:02:49 +0200 |  | ||||||
| Subject: [PATCH] mac80211: prevent attacks on TKIP/WEP as well |  | ||||||
|  |  | ||||||
| Similar to the issues fixed in previous patches, TKIP and WEP |  | ||||||
| should be protected even if for TKIP we have the Michael MIC |  | ||||||
| protecting it, and WEP is broken anyway. |  | ||||||
|  |  | ||||||
| However, this also somewhat protects potential other algorithms |  | ||||||
| that drivers might implement. |  | ||||||
|  |  | ||||||
| Cc: stable@vger.kernel.org |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2284,6 +2284,7 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  			 * next fragment has a sequential PN value. |  | ||||||
|  			 */ |  | ||||||
|  			entry->check_sequential_pn = true; |  | ||||||
| +			entry->is_protected = true; |  | ||||||
|  			entry->key_color = rx->key->color; |  | ||||||
|  			memcpy(entry->last_pn, |  | ||||||
|  			       rx->key->u.ccmp.rx_pn[queue], |  | ||||||
| @@ -2296,6 +2297,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)) { |  | ||||||
| +			entry->is_protected = true; |  | ||||||
| +			entry->key_color = rx->key->color; |  | ||||||
|  		} |  | ||||||
|  		return RX_QUEUED; |  | ||||||
|  	} |  | ||||||
| @@ -2337,6 +2341,14 @@ ieee80211_rx_h_defragment(struct ieee802 |  | ||||||
|  		if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) |  | ||||||
|  			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->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; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	skb_pull(rx->skb, ieee80211_hdrlen(fc)); |  | ||||||
| --- a/net/mac80211/sta_info.h |  | ||||||
| +++ b/net/mac80211/sta_info.h |  | ||||||
| @@ -455,7 +455,8 @@ struct ieee80211_fragment_entry { |  | ||||||
|  	u16 extra_len; |  | ||||||
|  	u16 last_frag; |  | ||||||
|  	u8 rx_queue; |  | ||||||
| -	bool check_sequential_pn; /* needed for CCMP/GCMP */ |  | ||||||
| +	u8 check_sequential_pn:1, /* needed for CCMP/GCMP */ |  | ||||||
| +	   is_protected:1; |  | ||||||
|  	u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |  | ||||||
|  	unsigned int key_color; |  | ||||||
|  }; |  | ||||||
| @@ -1,94 +0,0 @@ | |||||||
| From: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| Date: Tue, 11 May 2021 20:02:50 +0200 |  | ||||||
| Subject: [PATCH] mac80211: do not accept/forward invalid EAPOL frames |  | ||||||
|  |  | ||||||
| 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 <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2541,13 +2541,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)) |  | ||||||
| @@ -2572,8 +2572,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->list) |  | ||||||
|  #if LINUX_VERSION_IS_GEQ(4,19,0) |  | ||||||
| @@ -2617,6 +2637,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) { |  | ||||||
| @@ -1,68 +0,0 @@ | |||||||
| From: Wen Gong <wgong@codeaurora.org> |  | ||||||
| Date: Tue, 11 May 2021 20:02:51 +0200 |  | ||||||
| Subject: [PATCH] mac80211: extend protection against mixed key and |  | ||||||
|  fragment cache attacks |  | ||||||
|  |  | ||||||
| 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 <wgong@codeaurora.org> |  | ||||||
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |  | ||||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/net/mac80211/rx.c |  | ||||||
| +++ b/net/mac80211/rx.c |  | ||||||
| @@ -2239,6 +2239,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; |  | ||||||
| @@ -2297,7 +2298,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; |  | ||||||
|  		} |  | ||||||
| @@ -2342,13 +2345,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)); |  | ||||||
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens