cfg80211: update information elements in cached BSS struct
Sven Neumann [Thu, 9 Dec 2010 14:05:24 +0000 (15:05 +0100)]
When a cached BSS struct is updated because a new beacon was received,
the code replaces the cached information elements by the IEs from the
new beacon. However it did not update the pub.information_elements
and pub.len_information_elements fields leaving them either pointing
to the old beacon IEs or in an inconsistent state where the data is
replaced by the new beacon IEs but len_information_elements still has
its value from the first beacon.

Fix this by updating the information elements fields if they are
pointing to beacon IEs.

Signed-off-by: Sven Neumann <s.neumann@raumfeld.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

net/wireless/scan.c

index 503ebb8..ea427f4 100644 (file)
@@ -464,6 +464,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                if (res->pub.beacon_ies) {
                        size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
                        size_t ielen = res->pub.len_beacon_ies;
+                       bool information_elements_is_beacon_ies =
+                               (found->pub.information_elements ==
+                                found->pub.beacon_ies);
 
                        if (found->pub.beacon_ies &&
                            !found->beacon_ies_allocated &&
@@ -487,6 +490,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                                        found->pub.len_beacon_ies = ielen;
                                }
                        }
+
+                       /* Override IEs if they were from a beacon before */
+                       if (information_elements_is_beacon_ies) {
+                               found->pub.information_elements =
+                                       found->pub.beacon_ies;
+                               found->pub.len_information_elements =
+                                       found->pub.len_beacon_ies;
+                       }
                }
 
                kref_put(&res->ref, bss_release);