]> git.baikalelectronics.ru Git - kernel.git/commitdiff
wifi: cfg80211/mac80211: reject bad MBSSID elements
authorJohannes Berg <johannes.berg@intel.com>
Wed, 28 Sep 2022 20:01:37 +0000 (22:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 15 Oct 2022 05:54:40 +0000 (07:54 +0200)
commit 9744e1c02065575eeb158e1682c97b951ee680c1 upstream.

Per spec, the maximum value for the MaxBSSID ('n') indicator is 8,
and the minimum is 1 since a multiple BSSID set with just one BSSID
doesn't make sense (the # of BSSIDs is limited by 2^n).

Limit this in the parsing in both cfg80211 and mac80211, rejecting
any elements with an invalid value.

This fixes potentially bad shifts in the processing of these inside
the cfg80211_gen_new_bssid() function later.

I found this during the investigation of CVE-2022-41674 fixed by the
previous patch.

Fixes: b397b5577905 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Fixes: 97b231328c65 ("mac80211: support multi-bssid")
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mac80211/util.c
net/wireless/scan.c

index c1c117fdf318401b0132e02663de86e0c60e9f7f..a529861256e6280e451d9ba2640375b77889d27f 100644 (file)
@@ -1289,6 +1289,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
        for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
                if (elem->datalen < 2)
                        continue;
+               if (elem->data[0] < 1 || elem->data[0] > 8)
+                       continue;
 
                for_each_element(sub, elem->data + 1, elem->datalen - 1) {
                        u8 new_bssid[ETH_ALEN];
index b91185f4561babef7eac8caaccb0609746f0b1c2..e0dd0249d02620b0c6bbbde098eb604a2a417319 100644 (file)
@@ -1582,6 +1582,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
        for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
                if (elem->datalen < 4)
                        continue;
+               if (elem->data[0] < 1 || (int)elem->data[0] > 8)
+                       continue;
                for_each_element(sub, elem->data + 1, elem->datalen - 1) {
                        u8 profile_len;