aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/cfg80211.h
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-11-28 19:25:20 -0500
committerJohannes Berg <johannes.berg@intel.com>2012-11-30 07:42:20 -0500
commit9caf03640279e64d0ba36539b42daa1b43a49486 (patch)
treecb094a4a577f61421d1b402e16f0e68f151d5726 /include/net/cfg80211.h
parentb9a9ada14aab17f08c1d9735601f1097cdcfc6de (diff)
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>
Diffstat (limited to 'include/net/cfg80211.h')
-rw-r--r--include/net/cfg80211.h41
1 files changed, 27 insertions, 14 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 731b48fa238..8e6a6b73b9c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1206,6 +1206,18 @@ enum cfg80211_signal_type {
1206}; 1206};
1207 1207
1208/** 1208/**
1209 * struct cfg80211_bss_ie_data - BSS entry IE data
1210 * @rcu_head: internal use, for freeing
1211 * @len: length of the IEs
1212 * @data: IE data
1213 */
1214struct cfg80211_bss_ies {
1215 struct rcu_head rcu_head;
1216 int len;
1217 u8 data[];
1218};
1219
1220/**
1209 * struct cfg80211_bss - BSS description 1221 * struct cfg80211_bss - BSS description
1210 * 1222 *
1211 * This structure describes a BSS (which may also be a mesh network) 1223 * This structure describes a BSS (which may also be a mesh network)
@@ -1216,36 +1228,34 @@ enum cfg80211_signal_type {
1216 * @tsf: timestamp of last received update 1228 * @tsf: timestamp of last received update
1217 * @beacon_interval: the beacon interval as from the frame 1229 * @beacon_interval: the beacon interval as from the frame
1218 * @capability: the capability field in host byte order 1230 * @capability: the capability field in host byte order
1219 * @information_elements: the information elements (Note that there 1231 * @ies: the information elements (Note that there
1220 * is no guarantee that these are well-formed!); this is a pointer to 1232 * is no guarantee that these are well-formed!); this is a pointer to
1221 * either the beacon_ies or proberesp_ies depending on whether Probe 1233 * either the beacon_ies or proberesp_ies depending on whether Probe
1222 * Response frame has been received 1234 * Response frame has been received
1223 * @len_information_elements: total length of the information elements
1224 * @beacon_ies: the information elements from the last Beacon frame 1235 * @beacon_ies: the information elements from the last Beacon frame
1225 * @len_beacon_ies: total length of the beacon_ies
1226 * @proberesp_ies: the information elements from the last Probe Response frame 1236 * @proberesp_ies: the information elements from the last Probe Response frame
1227 * @len_proberesp_ies: total length of the proberesp_ies
1228 * @signal: signal strength value (type depends on the wiphy's signal_type) 1237 * @signal: signal strength value (type depends on the wiphy's signal_type)
1229 * @free_priv: function pointer to free private data 1238 * @free_priv: function pointer to free private data
1230 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 1239 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
1231 */ 1240 */
1232struct cfg80211_bss { 1241struct cfg80211_bss {
1242 u64 tsf;
1243
1233 struct ieee80211_channel *channel; 1244 struct ieee80211_channel *channel;
1234 1245
1235 u8 bssid[ETH_ALEN]; 1246 const struct cfg80211_bss_ies __rcu *ies;
1236 u64 tsf; 1247 const struct cfg80211_bss_ies __rcu *beacon_ies;
1248 const struct cfg80211_bss_ies __rcu *proberesp_ies;
1249
1250 void (*free_priv)(struct cfg80211_bss *bss);
1251
1252 s32 signal;
1253
1237 u16 beacon_interval; 1254 u16 beacon_interval;
1238 u16 capability; 1255 u16 capability;
1239 u8 *information_elements;
1240 size_t len_information_elements;
1241 u8 *beacon_ies;
1242 size_t len_beacon_ies;
1243 u8 *proberesp_ies;
1244 size_t len_proberesp_ies;
1245 1256
1246 s32 signal; 1257 u8 bssid[ETH_ALEN];
1247 1258
1248 void (*free_priv)(struct cfg80211_bss *bss);
1249 u8 priv[0] __attribute__((__aligned__(sizeof(void *)))); 1259 u8 priv[0] __attribute__((__aligned__(sizeof(void *))));
1250}; 1260};
1251 1261
@@ -1253,6 +1263,9 @@ struct cfg80211_bss {
1253 * ieee80211_bss_get_ie - find IE with given ID 1263 * ieee80211_bss_get_ie - find IE with given ID
1254 * @bss: the bss to search 1264 * @bss: the bss to search
1255 * @ie: the IE ID 1265 * @ie: the IE ID
1266 *
1267 * Note that the return value is an RCU-protected pointer, so
1268 * rcu_read_lock() must be held when calling this function.
1256 * Returns %NULL if not found. 1269 * Returns %NULL if not found.
1257 */ 1270 */
1258const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); 1271const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);