aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-05-23 19:06:09 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-05-23 19:06:09 -0400
commit4c8a9d4bfaf7dbc7d2168494904d79d22cc01db7 (patch)
tree44b63f3a3611d9b5231f1e5cd2fb0ff0d14a5c3d /net
parent5f38a11274f0e74ec0e499bc779d355510b39790 (diff)
mac80211: close AP_VLAN interfaces before unregistering all
Since Eric's commit efe117ab8 ("Speedup ieee80211_remove_interfaces") there's a bug in mac80211 when it unregisters with AP_VLAN interfaces up. If the AP_VLAN interface was registered after the AP it belongs to (which is the typical case) and then we get into this code path, unregister_netdevice_many() will crash because it isn't prepared to deal with interfaces being closed in the middle of it. Exactly this happens though, because we iterate the list, find the AP master this AP_VLAN belongs to and dev_close() the dependent VLANs. After this, unregister_netdevice_many() won't pick up the fact that the AP_VLAN is already down and will do it again, causing a crash. Cc: stable@vger.kernel.org [2.6.33+] Cc: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/iface.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 00e2238355f0..ceef64426a8d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1703,6 +1703,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
1703 1703
1704 ASSERT_RTNL(); 1704 ASSERT_RTNL();
1705 1705
1706 /*
1707 * Close all AP_VLAN interfaces first, as otherwise they
1708 * might be closed while the AP interface they belong to
1709 * is closed, causing unregister_netdevice_many() to crash.
1710 */
1711 list_for_each_entry(sdata, &local->interfaces, list)
1712 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1713 dev_close(sdata->dev);
1714
1706 mutex_lock(&local->iflist_mtx); 1715 mutex_lock(&local->iflist_mtx);
1707 list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { 1716 list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
1708 list_del(&sdata->list); 1717 list_del(&sdata->list);