From cec7dfa49775ce65270b977bea5fc0f928f97bdc 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 --- ...x-ieee80211_data_to_8023_exthdr-hand.patch | 97 +++++++++++++++++++ ...-not-drop-packets-smaller-than-the-L.patch | 25 +++++ 2 files changed, 122 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..220de79d9e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch @@ -0,0 +1,97 @@ +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,8 +557,6 @@ int ieee80211_data_to_8023_exthdr(struct + return -1; + + hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; +- if (skb->len < hdrlen + 8) +- return -1; + + /* convert IEEE 802.11 header + possible LLC headers into Ethernet + * header +@@ -572,8 +570,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 +592,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 +611,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 +627,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) && ++ if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0) && ++ 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))) ++ 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