Skip to content

Commit

Permalink
mac80211_hwsim: fix locking when iterating radios during ns exit
Browse files Browse the repository at this point in the history
The cleanup of radios during namespace exit has recently been reworked
to directly delete a radio while temporarily releasing the spinlock,
fixing a race condition between the work-queue execution and namespace
exits. However, the temporary unlock allows unsafe modifications on the
iterated list, resulting in a potential crash when continuing the
iteration of additional radios.

Move radios about to destroy to a temporary list, and clean that up
after releasing the spinlock once iteration is complete.

Fixes: 8cfd36a ("mac80211_hwsim: fix use-after-free bug in hwsim_exit_net")
Signed-off-by: Martin Willi <martin@strongswan.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Martin Willi authored and Johannes Berg committed Sep 26, 2018
1 parent 30fe6d5 commit 628980e
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -3646,6 +3646,7 @@ static __net_init int hwsim_init_net(struct net *net)
static void __net_exit hwsim_exit_net(struct net *net)
{
struct mac80211_hwsim_data *data, *tmp;
LIST_HEAD(list);

spin_lock_bh(&hwsim_radio_lock);
list_for_each_entry_safe(data, tmp, &hwsim_radios, list) {
Expand All @@ -3656,17 +3657,19 @@ static void __net_exit hwsim_exit_net(struct net *net)
if (data->netgroup == hwsim_net_get_netgroup(&init_net))
continue;

list_del(&data->list);
list_move(&data->list, &list);
rhashtable_remove_fast(&hwsim_radios_rht, &data->rht,
hwsim_rht_params);
hwsim_radios_generation++;
spin_unlock_bh(&hwsim_radio_lock);
}
spin_unlock_bh(&hwsim_radio_lock);

list_for_each_entry_safe(data, tmp, &list, list) {
list_del(&data->list);
mac80211_hwsim_del_radio(data,
wiphy_name(data->hw->wiphy),
NULL);
spin_lock_bh(&hwsim_radio_lock);
}
spin_unlock_bh(&hwsim_radio_lock);

ida_simple_remove(&hwsim_netgroup_ida, hwsim_net_get_netgroup(net));
}
Expand Down

0 comments on commit 628980e

Please sign in to comment.