lkml.org 
[lkml]   [2018]   [Oct]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.18 025/100] mac80211_hwsim: fix locking when iterating radios during ns exit
    Date
    From: Martin Willi <martin@strongswan.org>

    [ Upstream commit 628980e5c8f038f730582c6ee50b7410741cd96e ]

    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: 8cfd36a0b53a ("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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/wireless/mac80211_hwsim.c | 11 +++++++----
    1 file changed, 7 insertions(+), 4 deletions(-)

    diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
    index 80e2c8595c7c..6b90bef58293 100644
    --- a/drivers/net/wireless/mac80211_hwsim.c
    +++ b/drivers/net/wireless/mac80211_hwsim.c
    @@ -3523,6 +3523,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) {
    @@ -3533,17 +3534,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));
    }
    --
    2.17.1
    \
     
     \ /
      Last update: 2018-10-16 06:56    [W:4.023 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site