diff options
author | Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> | 2021-05-31 23:28:27 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-06-03 09:22:05 +0300 |
commit | e76511a6fbb5e568a2db4da8da5a120481c914fe (patch) | |
tree | c5de4178a47d289b75a38855ac1178e4cffb0b00 /net | |
parent | 229fa01b0bd72559e5c5b99e402f180e47ad86a8 (diff) | |
download | linux-e76511a6fbb5e568a2db4da8da5a120481c914fe.tar.xz |
mac80211: properly handle A-MSDUs that start with an RFC 1042 header
commit a1d5ff5651ea592c67054233b14b30bf4452999c upstream.
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>
Link: https://lore.kernel.org/r/20210511200110.0b2b886492f0.I23dd5d685fe16d3b0ec8106e8f01b59f499dffed@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/util.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c index 156a2a6337b9..0c7b9de1e7f1 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -409,8 +409,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) } EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, - enum nl80211_iftype iftype) +static int __ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype, bool is_amsdu) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u16 hdrlen, ethertype; @@ -504,7 +504,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, payload = skb->data + hdrlen; ethertype = (payload[6] << 8) | payload[7]; - if (likely((ether_addr_equal(payload, rfc1042_header) && + if (likely((!is_amsdu && ether_addr_equal(payload, rfc1042_header) && ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || ether_addr_equal(payload, bridge_tunnel_header))) { /* remove RFC1042 or Bridge-Tunnel encapsulation and @@ -525,6 +525,12 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, } return 0; } + +int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) +{ + return __ieee80211_data_to_8023(skb, addr, iftype, false); +} EXPORT_SYMBOL(ieee80211_data_to_8023); int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, |