]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: don't drop all unprotected public action frames
authorAvraham Stern <avraham.stern@intel.com>
Mon, 16 Oct 2023 11:52:48 +0000 (14:52 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 23 Oct 2023 11:25:30 +0000 (13:25 +0200)
Not all public action frames have a protected variant. When MFP is
enabled drop only public action frames that have a dual protected
variant.

Fixes: 76a3059cf124 ("wifi: mac80211: drop some unprotected action frames")
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20231016145213.2973e3c8d3bb.I6198b8d3b04cf4a97b06660d346caec3032f232a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/linux/ieee80211.h
net/mac80211/rx.c

index bd2f6e19c357a8185eddecff59d393e8554f1eba..b24fb80782c5a10d3af761403324c36bf5d3d452 100644 (file)
@@ -4355,6 +4355,35 @@ static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
        return mgmt->u.action.category == WLAN_CATEGORY_PUBLIC;
 }
 
+/**
+ * ieee80211_is_protected_dual_of_public_action - check if skb contains a
+ * protected dual of public action management frame
+ * @skb: the skb containing the frame, length will be checked
+ *
+ * Return: true if the skb contains a protected dual of public action
+ * management frame, false otherwise.
+ */
+static inline bool
+ieee80211_is_protected_dual_of_public_action(struct sk_buff *skb)
+{
+       u8 action;
+
+       if (!ieee80211_is_public_action((void *)skb->data, skb->len) ||
+           skb->len < IEEE80211_MIN_ACTION_SIZE + 1)
+               return false;
+
+       action = *(u8 *)(skb->data + IEEE80211_MIN_ACTION_SIZE);
+
+       return action != WLAN_PUB_ACTION_20_40_BSS_COEX &&
+               action != WLAN_PUB_ACTION_DSE_REG_LOC_ANN &&
+               action != WLAN_PUB_ACTION_MSMT_PILOT &&
+               action != WLAN_PUB_ACTION_TDLS_DISCOVER_RES &&
+               action != WLAN_PUB_ACTION_LOC_TRACK_NOTI &&
+               action != WLAN_PUB_ACTION_FTM_REQUEST &&
+               action != WLAN_PUB_ACTION_FTM_RESPONSE &&
+               action != WLAN_PUB_ACTION_FILS_DISCOVERY;
+}
+
 /**
  * _ieee80211_is_group_privacy_action - check if frame is a group addressed
  * privacy action frame
index e751cda5eef69e4a8842ffa7a4706f9a8c30d8a9..8f6b6f56b65b4353ea0be6a99358b30970dfcb29 100644 (file)
@@ -2468,8 +2468,7 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
 
                /* drop unicast public action frames when using MPF */
                if (is_unicast_ether_addr(mgmt->da) &&
-                   ieee80211_is_public_action((void *)rx->skb->data,
-                                              rx->skb->len))
+                   ieee80211_is_protected_dual_of_public_action(rx->skb))
                        return -EACCES;
        }