]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mac80211: properly handle A-MSDUs that start with an RFC 1042 header
authorMathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
Mon, 31 May 2021 20:28:27 +0000 (22:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Jun 2021 06:22:05 +0000 (08:22 +0200)
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>
net/wireless/util.c

index 156a2a6337b92d55c39070ffa1ed3ea0972fff2b..0c7b9de1e7f19ef8c05f5030175b61b6ac9be499 100644 (file)
@@ -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,