aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-02-25 10:27:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:42:00 -0500
commite6a5ddf20886206caf1c4a2431f6ff01198ab0f7 (patch)
treed299c8113e8b0c96368165fbde3da440f1ea7142 /net
parent2485f7105f20f85c2dbebc67be6b2cb97175fa7e (diff)
mac80211: safely free beacon in ieee80211_if_reinit
If ieee80211_if_reinit() is called from ieee80211_unregister_hw() then it is possible that the driver will still request a beacon (it is allowed to until ieee80211_unregister_hw() has returned.) This means we need to use an RCU-protected write to the beacon information even in this function. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_iface.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index f66f1ddc3fda..0d6824bca92b 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -193,6 +193,7 @@ void ieee80211_if_reinit(struct net_device *dev)
193 /* Remove all virtual interfaces that use this BSS 193 /* Remove all virtual interfaces that use this BSS
194 * as their sdata->bss */ 194 * as their sdata->bss */
195 struct ieee80211_sub_if_data *tsdata, *n; 195 struct ieee80211_sub_if_data *tsdata, *n;
196 struct beacon_data *beacon;
196 197
197 list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { 198 list_for_each_entry_safe(tsdata, n, &local->interfaces, list) {
198 if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { 199 if (tsdata != sdata && tsdata->bss == &sdata->u.ap) {
@@ -210,7 +211,10 @@ void ieee80211_if_reinit(struct net_device *dev)
210 } 211 }
211 } 212 }
212 213
213 kfree(sdata->u.ap.beacon); 214 beacon = sdata->u.ap.beacon;
215 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
216 synchronize_rcu();
217 kfree(beacon);
214 218
215 while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { 219 while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
216 local->total_ps_buffered--; 220 local->total_ps_buffered--;