]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: cfg80211: correct S1G beacon length calculation
authorJohannes Berg <johannes.berg@intel.com>
Wed, 24 Jul 2024 11:29:12 +0000 (13:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Aug 2024 10:57:50 +0000 (12:57 +0200)
[ Upstream commit 6873cc4416078202882691b424fcca5b5fb1a94d ]

The minimum header length calculation (equivalent to the start
of the elements) for the S1G long beacon erroneously required
only up to the start of u.s1g_beacon rather than the start of
u.s1g_beacon.variable. Fix that, and also shuffle the branches
around a bit to not assign useless values that are overwritten
later.

Reported-by: syzbot+0f3afa93b91202f21939@syzkaller.appspotmail.com
Fixes: 9eaffe5078ca ("cfg80211: convert S1G beacon to scan results")
Link: https://patch.msgid.link/20240724132912.9662972db7c1.I8779675b5bbda4994cc66f876b6b87a2361c3c0b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/wireless/scan.c

index 0222ede0feb60b1bab05f12b6db3fdddafa101d3..292b530a6dd314edb656a579798f8d610761d92f 100644 (file)
@@ -3136,8 +3136,7 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
                               struct ieee80211_mgmt *mgmt, size_t len,
                               gfp_t gfp)
 {
-       size_t min_hdr_len = offsetof(struct ieee80211_mgmt,
-                                     u.probe_resp.variable);
+       size_t min_hdr_len;
        struct ieee80211_ext *ext = NULL;
        enum cfg80211_bss_frame_type ftype;
        u16 beacon_interval;
@@ -3160,10 +3159,16 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
 
        if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
                ext = (void *) mgmt;
-               min_hdr_len = offsetof(struct ieee80211_ext, u.s1g_beacon);
                if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
                        min_hdr_len = offsetof(struct ieee80211_ext,
                                               u.s1g_short_beacon.variable);
+               else
+                       min_hdr_len = offsetof(struct ieee80211_ext,
+                                              u.s1g_beacon.variable);
+       } else {
+               /* same for beacons */
+               min_hdr_len = offsetof(struct ieee80211_mgmt,
+                                      u.probe_resp.variable);
        }
 
        if (WARN_ON(len < min_hdr_len))