From: Johannes Berg Date: Mon, 25 Feb 2008 15:27:42 +0000 (+0100) Subject: mac80211: safely free beacon in ieee80211_if_reinit X-Git-Tag: v2.6.26-rc1~1138^2~530^2~3 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=e6a5ddf20886206caf1c4a2431f6ff01198ab0f7;p=linux-2.6-omap-h63xx.git 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 Signed-off-by: John W. Linville --- diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c index f66f1ddc3fd..0d6824bca92 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) /* Remove all virtual interfaces that use this BSS * as their sdata->bss */ struct ieee80211_sub_if_data *tsdata, *n; + struct beacon_data *beacon; list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { @@ -210,7 +211,10 @@ void ieee80211_if_reinit(struct net_device *dev) } } - kfree(sdata->u.ap.beacon); + beacon = sdata->u.ap.beacon; + rcu_assign_pointer(sdata->u.ap.beacon, NULL); + synchronize_rcu(); + kfree(beacon); while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { local->total_ps_buffered--;