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;
|
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
|
||||||
@@ -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,
|
.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);
|
||||||
@@ -4309,6 +4311,17 @@ void ieee80211_check_fast_rx(struct sta_
|
@@ -4310,6 +4312,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);
|
||||||
@@ -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);
|
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)
|
||||||
{
|
{
|
||||||
@@ -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);
|
} 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
|
||||||
@@ -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))
|
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;
|
||||||
|
|
||||||
@@ -4488,12 +4574,6 @@ static bool ieee80211_invoke_fast_rx(str
|
@@ -4489,12 +4575,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);
|
||||||
@@ -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 */
|
/* 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;
|
||||||
}
|
}
|
||||||
@@ -4611,6 +4643,47 @@ static bool ieee80211_prepare_and_rx_han
|
@@ -4612,6 +4644,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.
|
||||||
@@ -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.
|
* if it was previously present.
|
||||||
* Also, frames with less than 16 bytes are dropped.
|
* 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);
|
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||||
--- a/net/mac80211/rx.c
|
--- a/net/mac80211/rx.c
|
||||||
+++ b/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;
|
return RX_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|||||||
static ieee80211_rx_result debug_noinline
|
static ieee80211_rx_result debug_noinline
|
||||||
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
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))
|
!mesh_path_sel_is_hwmp(sdata))
|
||||||
break;
|
break;
|
||||||
goto queue;
|
goto queue;
|
||||||
|
|||||||
Reference in New Issue
Block a user