wifi: cfg80211: fix S1G beacon head validation in nl80211
authorLachlan Hodges <lachlan.hodges@morsemicro.com>
Thu, 26 Jun 2025 11:51:18 +0000 (21:51 +1000)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 30 Jun 2025 13:33:46 +0000 (15:33 +0200)
S1G beacons contain fixed length optional fields that precede the
variable length elements, ensure we take this into account when
validating the beacon. This particular case was missed in
1e1f706fc2ce ("wifi: cfg80211/mac80211: correctly parse S1G
beacon optional elements").

Fixes: 1d47f1198d58 ("nl80211: correctly validate S1G beacon head")
Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
Link: https://patch.msgid.link/20250626115118.68660-1-lachlan.hodges@morsemicro.com
[shorten/reword subject]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index 85f139016da21c2bc77606ba22cd1c6e60d8fe31..50202d170f3a741ddd15baf92c87a9677961dc2e 100644 (file)
@@ -229,6 +229,7 @@ static int validate_beacon_head(const struct nlattr *attr,
        unsigned int len = nla_len(attr);
        const struct element *elem;
        const struct ieee80211_mgmt *mgmt = (void *)data;
+       const struct ieee80211_ext *ext;
        unsigned int fixedlen, hdrlen;
        bool s1g_bcn;
 
@@ -237,8 +238,10 @@ static int validate_beacon_head(const struct nlattr *attr,
 
        s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
        if (s1g_bcn) {
-               fixedlen = offsetof(struct ieee80211_ext,
-                                   u.s1g_beacon.variable);
+               ext = (struct ieee80211_ext *)mgmt;
+               fixedlen =
+                       offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
+                       ieee80211_s1g_optional_len(ext->frame_control);
                hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon);
        } else {
                fixedlen = offsetof(struct ieee80211_mgmt,