mac80211: always allocate struct ieee802_11_elems

As the 802.11 spec evolves, we need to parse more and more
elements. This is causing the struct to grow, and we can no
longer get away with putting it on the stack.

Change the API to always dynamically allocate and return an
allocated pointer that must be kfree()d later.

As an alternative, I contemplated a scheme whereby we'd say
in the code which elements we needed, e.g.

    DECLARE_ELEMENT_PARSER(elems,
                           SUPPORTED_CHANNELS,
                           CHANNEL_SWITCH,
                           EXT(KEY_DELIVERY));

    ieee802_11_parse_elems(..., &elems, ...);

and while I think this is possible and will save us a lot
since most individual places only care about a small subset
of the elements, it ended up being a bit more work since a
lot of places do the parsing and then pass the struct to
other functions, sometimes with multiple levels.

Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dce8412..ca8008b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1391,8 +1391,8 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 
 static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
 					    struct ieee802_11_elems *elems,
-					    u8 *transmitter_bssid,
-					    u8 *bss_bssid,
+					    const u8 *transmitter_bssid,
+					    const u8 *bss_bssid,
 					    u8 *nontransmitted_profile)
 {
 	const struct element *elem, *sub;
@@ -1457,16 +1457,20 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
 	return found ? profile_len : 0;
 }
 
-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
-				struct ieee802_11_elems *elems,
-				u64 filter, u32 crc, u8 *transmitter_bssid,
-				u8 *bss_bssid)
+struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
+						    bool action, u64 filter,
+						    u32 crc,
+						    const u8 *transmitter_bssid,
+						    const u8 *bss_bssid)
 {
+	struct ieee802_11_elems *elems;
 	const struct element *non_inherit = NULL;
 	u8 *nontransmitted_profile;
 	int nontransmitted_profile_len = 0;
 
-	memset(elems, 0, sizeof(*elems));
+	elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
+	if (!elems)
+		return NULL;
 	elems->ie_start = start;
 	elems->total_len = len;
 
@@ -1513,6 +1517,8 @@ void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 	kfree(nontransmitted_profile);
 
 	elems->crc = crc;
+
+	return elems;
 }
 
 void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,