| From 8f033d2becc24aa6bfd2a5c104407963560caabc Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Wed, 28 Sep 2022 22:01:37 +0200 |
| Subject: wifi: cfg80211/mac80211: reject bad MBSSID elements |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 8f033d2becc24aa6bfd2a5c104407963560caabc 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: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") |
| Fixes: 78ac51f81532 ("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 | 2 ++ |
| net/wireless/scan.c | 2 ++ |
| 2 files changed, 4 insertions(+) |
| |
| --- a/net/mac80211/util.c |
| +++ b/net/mac80211/util.c |
| @@ -1439,6 +1439,8 @@ static size_t ieee802_11_find_bssid_prof |
| 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]; |
| --- a/net/wireless/scan.c |
| +++ b/net/wireless/scan.c |
| @@ -2143,6 +2143,8 @@ static void cfg80211_parse_mbssid_data(s |
| 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; |
| |