Kalle Valo says:
[linux-block.git] / net / mac80211 / util.c
index 53217dc3f932b30c245794226c79d3c534e632dd..6f5407038459d03cc3ceaa4ac29a66c3da570a57 100644 (file)
@@ -1450,6 +1450,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];
@@ -1648,7 +1650,7 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
        const struct element *non_inherit = NULL;
        u8 *nontransmitted_profile;
        int nontransmitted_profile_len = 0;
-       size_t scratch_len = params->scratch_len ?: 2 * params->len;
+       size_t scratch_len = params->scratch_len ?: 3 * params->len;
 
        elems = kzalloc(sizeof(*elems) + scratch_len, GFP_ATOMIC);
        if (!elems)
@@ -1658,17 +1660,16 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
        elems->scratch_len = scratch_len;
        elems->scratch_pos = elems->scratch;
 
-       nontransmitted_profile = kmalloc(params->len, GFP_ATOMIC);
-       if (nontransmitted_profile) {
-               nontransmitted_profile_len =
-                       ieee802_11_find_bssid_profile(params->start, params->len,
-                                                     elems, params->bss,
-                                                     nontransmitted_profile);
-               non_inherit =
-                       cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
-                                              nontransmitted_profile,
-                                              nontransmitted_profile_len);
-       }
+       nontransmitted_profile = elems->scratch_pos;
+       nontransmitted_profile_len =
+               ieee802_11_find_bssid_profile(params->start, params->len,
+                                             elems, params->bss,
+                                             nontransmitted_profile);
+       elems->scratch_pos += nontransmitted_profile_len;
+       elems->scratch_len -= nontransmitted_profile_len;
+       non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+                                            nontransmitted_profile,
+                                            nontransmitted_profile_len);
 
        elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit);
 
@@ -1704,8 +1705,6 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
            offsetofend(struct ieee80211_bssid_index, dtim_count))
                elems->dtim_count = elems->bssid_index->dtim_count;
 
-       kfree(nontransmitted_profile);
-
        return elems;
 }