From 43689bf2cd8e2e61e37e252b56da53cfe13de710 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 28 Sep 2022 22:01:37 +0200 Subject: wifi: cfg80211/mac80211: reject bad MBSSID elements 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 Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net/mac80211/util.c') diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c1c117fdf318..a529861256e6 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -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]; -- cgit v1.2.3 From 7f441a6c90fe165b57b8514a5ae360344edc6d6d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 14 Oct 2022 18:47:03 +0200 Subject: mac80211: mlme: find auth challenge directly There's no need to parse all elements etc. just to find the authentication challenge - use cfg80211_find_elem() instead. This also allows us to remove WLAN_EID_CHALLENGE handling from the element parsing entirely. Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/util.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'net/mac80211/util.c') diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a529861256e6..1ba37f67a2a0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1006,10 +1006,6 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, } else elem_parse_failed = true; break; - case WLAN_EID_CHALLENGE: - elems->challenge = pos; - elems->challenge_len = elen; - break; case WLAN_EID_VENDOR_SPECIFIC: if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && pos[2] == 0xf2) { -- cgit v1.2.3 From 0cb5be43dc4b79da010522f79a06fa56f944d3cd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 14 Oct 2022 18:47:05 +0200 Subject: wifi: mac80211: fix MBSSID parsing use-after-free Commit ff05d4b45dd89b922578dac497dcabf57cf771c6 upstream. This is a different version of the commit, changed to store the non-transmitted profile in the elems, and freeing it in the few places where it's relevant, since that is only the case when the last argument for parsing (the non-tx BSSID) is non-NULL. When we parse a multi-BSSID element, we might point some element pointers into the allocated nontransmitted_profile. However, we free this before returning, causing UAF when the relevant pointers in the parsed elements are accessed. Fix this by not allocating the scratch buffer separately but as part of the returned structure instead, that way, there are no lifetime issues with it. The scratch buffer introduction as part of the returned data here is taken from MLO feature work done by Ilan. This fixes CVE-2022-42719. Fixes: 5023b14cf4df ("mac80211: support profile split between elements") Co-developed-by: Ilan Peer Signed-off-by: Ilan Peer Reviewed-by: Kees Cook Signed-off-by: Johannes Berg Signed-off-by: Greg Kroah-Hartman --- net/mac80211/util.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'net/mac80211/util.c') diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1ba37f67a2a0..6223af1c3457 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1363,6 +1363,11 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, nontransmitted_profile, nontransmitted_profile_len); + if (!nontransmitted_profile_len) { + nontransmitted_profile_len = 0; + kfree(nontransmitted_profile); + nontransmitted_profile = NULL; + } } crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter, @@ -1392,7 +1397,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, offsetofend(struct ieee80211_bssid_index, dtim_count)) elems->dtim_count = elems->bssid_index->dtim_count; - kfree(nontransmitted_profile); + elems->nontx_profile = nontransmitted_profile; return crc; } -- cgit v1.2.3