cfg80211: fix BSS struct IE access races

When a BSS struct is updated, the IEs are currently
overwritten or freed. This can lead to races if some
other CPU is accessing the BSS struct and using the
IEs concurrently.

Fix this by always allocating the IEs in a new struct
that holds the data and length and protecting access
to this new struct with RCU.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 3cce6e4..16d76a8 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -688,10 +688,13 @@
 
 const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
 {
-	if (bss->information_elements == NULL)
+	const struct cfg80211_bss_ies *ies;
+
+	ies = rcu_dereference(bss->ies);
+	if (!ies)
 		return NULL;
-	return cfg80211_find_ie(ie, bss->information_elements,
-				 bss->len_information_elements);
+
+	return cfg80211_find_ie(ie, ies->data, ies->len);
 }
 EXPORT_SYMBOL(ieee80211_bss_get_ie);