From a26f7e61e8a94c192735c71e30500809de21e31f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 7 Oct 2022 11:29:54 +0200 Subject: [PATCH] mac80211: fix issues with receiving small STP packets Signed-off-by: Felix Fietkau (cherry-picked from commit cec7dfa49775ce65270b977bea5fc0f928f97bdc) (cherry-picked from commit f6c359a65528b994e97235b5f0b0d02d6cdad918) --- ...x-ieee80211_data_to_8023_exthdr-hand.patch | 99 +++++++++++++++++++ ...-not-drop-packets-smaller-than-the-L.patch | 25 +++++ 2 files changed, 124 insertions(+) create mode 100644 package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch create mode 100644 package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch diff --git a/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch b/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch new file mode 100644 index 0000000000..161c7d6c8f --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch @@ -0,0 +1,99 @@ +From: Felix Fietkau +Date: Fri, 7 Oct 2022 10:54:47 +0200 +Subject: [PATCH] wifi: cfg80211: fix ieee80211_data_to_8023_exthdr + handling of small packets + +STP topology change notification packets only have a payload of 7 bytes, +so they get dropped due to the skb->len < hdrlen + 8 check. +Fix this by removing skb->len based checks and instead check the return code +on the skb_copy_bits calls. + +Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") +Reported-by: Chad Monroe +Signed-off-by: Felix Fietkau +--- + +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -557,7 +557,7 @@ int ieee80211_data_to_8023_exthdr(struct + return -1; + + hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; +- if (skb->len < hdrlen + 8) ++ if (skb->len < hdrlen) + return -1; + + /* convert IEEE 802.11 header + possible LLC headers into Ethernet +@@ -572,8 +572,9 @@ int ieee80211_data_to_8023_exthdr(struct + memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); + +- if (iftype == NL80211_IFTYPE_MESH_POINT) +- skb_copy_bits(skb, hdrlen, &mesh_flags, 1); ++ if (iftype == NL80211_IFTYPE_MESH_POINT && ++ skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) ++ return -1; + + mesh_flags &= MESH_FLAGS_AE; + +@@ -593,11 +594,12 @@ int ieee80211_data_to_8023_exthdr(struct + if (iftype == NL80211_IFTYPE_MESH_POINT) { + if (mesh_flags == MESH_FLAGS_AE_A4) + return -1; +- if (mesh_flags == MESH_FLAGS_AE_A5_A6) { +- skb_copy_bits(skb, hdrlen + +- offsetof(struct ieee80211s_hdr, eaddr1), +- tmp.h_dest, 2 * ETH_ALEN); +- } ++ if (mesh_flags == MESH_FLAGS_AE_A5_A6 && ++ skb_copy_bits(skb, hdrlen + ++ offsetof(struct ieee80211s_hdr, eaddr1), ++ tmp.h_dest, 2 * ETH_ALEN) < 0) ++ return -1; ++ + hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); + } + break; +@@ -611,10 +613,11 @@ int ieee80211_data_to_8023_exthdr(struct + if (iftype == NL80211_IFTYPE_MESH_POINT) { + if (mesh_flags == MESH_FLAGS_AE_A5_A6) + return -1; +- if (mesh_flags == MESH_FLAGS_AE_A4) +- skb_copy_bits(skb, hdrlen + +- offsetof(struct ieee80211s_hdr, eaddr1), +- tmp.h_source, ETH_ALEN); ++ if (mesh_flags == MESH_FLAGS_AE_A4 && ++ skb_copy_bits(skb, hdrlen + ++ offsetof(struct ieee80211s_hdr, eaddr1), ++ tmp.h_source, ETH_ALEN) < 0) ++ return -1; + hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); + } + break; +@@ -626,18 +629,18 @@ int ieee80211_data_to_8023_exthdr(struct + break; + } + +- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); +- tmp.h_proto = payload.proto; +- +- 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))) ++ if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && ++ ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && ++ payload.proto != htons(ETH_P_AARP) && ++ payload.proto != htons(ETH_P_IPX)) || ++ ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + hdrlen += ETH_ALEN + 2; +- else ++ tmp.h_proto = payload.proto; ++ } else { + tmp.h_proto = htons(skb->len - hdrlen); ++ } + + pskb_pull(skb, hdrlen); + diff --git a/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch b/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch new file mode 100644 index 0000000000..16cafc447c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch @@ -0,0 +1,25 @@ +From: Felix Fietkau +Date: Fri, 7 Oct 2022 10:58:26 +0200 +Subject: [PATCH] wifi: mac80211: do not drop packets smaller than the + LLC-SNAP header on fast-rx + +Since STP TCN frames are only 7 bytes, the pskb_may_pull call returns an error. +Instead of dropping those packets, bump them back to the slow path for proper +processing. + +Fixes: 49ddf8e6e234 ("mac80211: add fast-rx path") +Reported-by: Chad Monroe +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4601,7 +4601,7 @@ static bool ieee80211_invoke_fast_rx(str + + if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { + if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) +- goto drop; ++ return false; + + payload = (void *)(skb->data + snap_offs); + -- 2.30.2