mac80211: backport fix for dealing with stripped IV on rx
This fixes potental rx drop issues
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry-picked from commit 68189835ac)
			
			
This commit is contained in:
		| @@ -0,0 +1,26 @@ | ||||
| From: Xing Song <xing.song@mediatek.com> | ||||
| Date: Mon, 1 Nov 2021 10:46:57 +0800 | ||||
| Subject: [PATCH] mac80211: do not access the IV when it was stripped | ||||
|  | ||||
| ieee80211_get_keyid() will return false value if IV has been stripped, | ||||
| such as return 0 for IP/ARP frames due to LLC header, and return -EINVAL | ||||
| for disassociation frames due to its length... etc. Don't try to access | ||||
| it if it's not present. | ||||
|  | ||||
| Signed-off-by: Xing Song <xing.song@mediatek.com> | ||||
| Link: https://lore.kernel.org/r/20211101024657.143026-1-xing.song@mediatek.com | ||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
| --- | ||||
|  | ||||
| --- a/net/mac80211/rx.c | ||||
| +++ b/net/mac80211/rx.c | ||||
| @@ -1945,7 +1945,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_ | ||||
|  		int keyid = rx->sta->ptk_idx; | ||||
|  		sta_ptk = rcu_dereference(rx->sta->ptk[keyid]); | ||||
|   | ||||
| -		if (ieee80211_has_protected(fc)) { | ||||
| +		if (ieee80211_has_protected(fc) && | ||||
| +		    !(status->flag & RX_FLAG_IV_STRIPPED)) { | ||||
|  			cs = rx->sta->cipher_scheme; | ||||
|  			keyid = ieee80211_get_keyid(rx->skb, cs); | ||||
|   | ||||
| @@ -183,7 +183,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; | ||||
| --- a/net/mac80211/rx.c | ||||
| +++ b/net/mac80211/rx.c | ||||
| @@ -4196,7 +4196,9 @@ void ieee80211_check_fast_rx(struct sta_ | ||||
| @@ -4197,7 +4197,9 @@ void ieee80211_check_fast_rx(struct sta_ | ||||
|  		.vif_type = sdata->vif.type, | ||||
|  		.control_port_protocol = sdata->control_port_protocol, | ||||
|  	}, *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 */ | ||||
|  	__acquire(check_fast_rx); | ||||
| @@ -4309,6 +4311,17 @@ void ieee80211_check_fast_rx(struct sta_ | ||||
| @@ -4310,6 +4312,17 @@ void ieee80211_check_fast_rx(struct sta_ | ||||
|  	if (assign) | ||||
|  		new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); | ||||
|   | ||||
| @@ -211,7 +211,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	spin_lock_bh(&sta->lock); | ||||
|  	old = rcu_dereference_protected(sta->fast_rx, true); | ||||
|  	rcu_assign_pointer(sta->fast_rx, new); | ||||
| @@ -4355,6 +4368,108 @@ void ieee80211_check_fast_rx_iface(struc | ||||
| @@ -4356,6 +4369,108 @@ void ieee80211_check_fast_rx_iface(struc | ||||
|  	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, | ||||
|  				     struct ieee80211_fast_rx *fast_rx) | ||||
|  { | ||||
| @@ -4375,9 +4490,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
| @@ -4376,9 +4491,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
|  	} addrs __aligned(2); | ||||
|  	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 | ||||
|  	 * to a common data structure; drivers can implement that per queue | ||||
|  	 * but we don't have that information in mac80211 | ||||
| @@ -4451,32 +4563,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
| @@ -4452,32 +4564,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
|  	    pskb_trim(skb, skb->len - fast_rx->icv_len)) | ||||
|  		goto drop; | ||||
|   | ||||
| @@ -363,7 +363,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	if (rx->key && !ieee80211_has_protected(hdr->frame_control)) | ||||
|  		goto drop; | ||||
|   | ||||
| @@ -4488,12 +4574,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
| @@ -4489,12 +4575,6 @@ static bool ieee80211_invoke_fast_rx(str | ||||
|  		return true; | ||||
|  	} | ||||
|   | ||||
| @@ -376,7 +376,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	/* do the header conversion - first grab the addresses */ | ||||
|  	ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); | ||||
|  	ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); | ||||
| @@ -4502,62 +4582,14 @@ static bool ieee80211_invoke_fast_rx(str | ||||
| @@ -4503,62 +4583,14 @@ static bool ieee80211_invoke_fast_rx(str | ||||
|  	/* push the addresses in front */ | ||||
|  	memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); | ||||
|   | ||||
| @@ -443,7 +443,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	stats->dropped++; | ||||
|  	return true; | ||||
|  } | ||||
| @@ -4611,6 +4643,47 @@ static bool ieee80211_prepare_and_rx_han | ||||
| @@ -4612,6 +4644,47 @@ static bool ieee80211_prepare_and_rx_han | ||||
|  	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 | ||||
|   * be called with rcu_read_lock protection. | ||||
| @@ -4848,15 +4921,20 @@ void ieee80211_rx_list(struct ieee80211_ | ||||
| @@ -4849,15 +4922,20 @@ void ieee80211_rx_list(struct ieee80211_ | ||||
|  	 * if it was previously present. | ||||
|  	 * Also, frames with less than 16 bytes are dropped. | ||||
|  	 */ | ||||
|   | ||||
| @@ -187,7 +187,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
|  	INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); | ||||
| --- a/net/mac80211/rx.c | ||||
| +++ b/net/mac80211/rx.c | ||||
| @@ -3209,6 +3209,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802 | ||||
| @@ -3210,6 +3210,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802 | ||||
|  	return RX_CONTINUE; | ||||
|  } | ||||
|   | ||||
| @@ -256,7 +256,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
|  static ieee80211_rx_result debug_noinline | ||||
|  ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | ||||
|  { | ||||
| @@ -3488,6 +3550,17 @@ ieee80211_rx_h_action(struct ieee80211_r | ||||
| @@ -3489,6 +3551,17 @@ ieee80211_rx_h_action(struct ieee80211_r | ||||
|  		    !mesh_path_sel_is_hwmp(sdata)) | ||||
|  			break; | ||||
|  		goto queue; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau