mac80211: fix virtual monitor interface iteration

During channel context assignment, the interface should
be found by interface iteration, so we need to assign the
pointer before the channel context.

Reported-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Tested-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2014-01-29 13:28:02 +01:00
parent 338f977f4e
commit fab57a6cc2
1 changed files with 8 additions and 4 deletions

View File

@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
return ret; return ret;
} }
mutex_lock(&local->iflist_mtx);
rcu_assign_pointer(local->monitor_sdata, sdata);
mutex_unlock(&local->iflist_mtx);
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
IEEE80211_CHANCTX_EXCLUSIVE); IEEE80211_CHANCTX_EXCLUSIVE);
mutex_unlock(&local->mtx); mutex_unlock(&local->mtx);
if (ret) { if (ret) {
mutex_lock(&local->iflist_mtx);
rcu_assign_pointer(local->monitor_sdata, NULL);
mutex_unlock(&local->iflist_mtx);
synchronize_net();
drv_remove_interface(local, sdata); drv_remove_interface(local, sdata);
kfree(sdata); kfree(sdata);
return ret; return ret;
} }
mutex_lock(&local->iflist_mtx);
rcu_assign_pointer(local->monitor_sdata, sdata);
mutex_unlock(&local->iflist_mtx);
return 0; return 0;
} }