aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-05-24 01:06:09 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-07 12:46:48 -0700
commit2ea00641254d9e6d3e84b6f2f1b295563d3e95e6 (patch)
treec94566bbc91abbe1a99fd8c64ba2c4be5f0940bf /net
parent93a327fcdef0c9e089ba7b347780cf9eaa92677f (diff)
downloadkernel_samsung_aries-2ea00641254d9e6d3e84b6f2f1b295563d3e95e6.zip
kernel_samsung_aries-2ea00641254d9e6d3e84b6f2f1b295563d3e95e6.tar.gz
kernel_samsung_aries-2ea00641254d9e6d3e84b6f2f1b295563d3e95e6.tar.bz2
mac80211: close AP_VLAN interfaces before unregistering all
commit c8aa22db0112f640ac6631347f850879c621840b upstream. 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. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 65f3764c..bd1ef84 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1242,6 +1242,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
ASSERT_RTNL();
+ /*
+ * Close all AP_VLAN interfaces first, as otherwise they
+ * might be closed while the AP interface they belong to
+ * is closed, causing unregister_netdevice_many() to crash.
+ */
+ list_for_each_entry(sdata, &local->interfaces, list)
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ dev_close(sdata->dev);
+
mutex_lock(&local->iflist_mtx);
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
list_del(&sdata->list);