blob: 804b02eb3063e52d06cebc9344d36fa666ccc03b [file] [log] [blame]
developer88605f72023-02-15 16:38:49 +08001From: Felix Fietkau <nbd@nbd.name>
2Date: Thu, 1 Dec 2022 14:57:30 +0100
3Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for
4 mesh
5
6ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and
7ieee80211_frame_allowed.
8
9Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes
10and is called earlier, it needs to check the decryptions status and if the
11packet is using the control protocol on its own, instead of deferring to
12the later call from ieee80211_frame_allowed.
13
14Because of that, ieee80211_drop_unencrypted has a mesh specific check
15that skips over the mesh header in order to check the payload protocol.
16This code is invalid when called from ieee80211_frame_allowed, since that
17happens after the 802.11->802.3 conversion.
18
19Fix this by moving the mesh specific check directly into
20ieee80211_rx_h_mesh_fwding.
21
22Signed-off-by: Felix Fietkau <nbd@nbd.name>
23Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name
24Signed-off-by: Johannes Berg <johannes.berg@intel.com>
25---
26
27--- a/net/mac80211/rx.c
28+++ b/net/mac80211/rx.c
29@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control
30
31 static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
32 {
33- struct ieee80211_hdr *hdr = (void *)rx->skb->data;
34 struct sk_buff *skb = rx->skb;
35 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
36
37@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st
38 if (status->flag & RX_FLAG_DECRYPTED)
39 return 0;
40
41- /* check mesh EAPOL frames first */
42- if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) &&
43- ieee80211_is_data(fc))) {
44- struct ieee80211s_hdr *mesh_hdr;
45- u16 hdr_len = ieee80211_hdrlen(fc);
46- u16 ethertype_offset;
47- __be16 ethertype;
48-
49- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr))
50- goto drop_check;
51-
52- /* make sure fixed part of mesh header is there, also checks skb len */
53- if (!pskb_may_pull(rx->skb, hdr_len + 6))
54- goto drop_check;
55-
56- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len);
57- ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) +
58- sizeof(rfc1042_header);
59-
60- if (skb_copy_bits(rx->skb, ethertype_offset, &ethertype, 2) == 0 &&
61- ethertype == rx->sdata->control_port_protocol)
62- return 0;
63- }
64-
65-drop_check:
66 /* Drop unencrypted frames if key is set. */
67 if (unlikely(!ieee80211_has_protected(fc) &&
68 !ieee80211_is_any_nullfunc(fc) &&
69@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
70 hdr = (struct ieee80211_hdr *) skb->data;
71 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
72
73- if (ieee80211_drop_unencrypted(rx, hdr->frame_control))
74- return RX_DROP_MONITOR;
75+ if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) {
76+ int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) +
77+ sizeof(rfc1042_header);
78+ __be16 ethertype;
79+
80+ if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) ||
81+ skb_copy_bits(rx->skb, offset, &ethertype, 2) != 0 ||
82+ ethertype != rx->sdata->control_port_protocol)
83+ return RX_DROP_MONITOR;
84+ }
85
86 /* frame is in RMC, don't forward */
87 if (ieee80211_is_data(hdr->frame_control) &&