• Johannes Berg's avatar
    mac80211: fix RX A-MPDU session reorder timer deletion · 788211d8
    Johannes Berg authored
    There's an issue with the way the RX A-MPDU reorder timer is
    deleted that can cause a kernel crash like this:
    
     * tid_rx is removed - call_rcu(ieee80211_free_tid_rx)
     * station is destroyed
     * reorder timer fires before ieee80211_free_tid_rx() runs,
       accessing the station, thus potentially crashing due to
       the use-after-free
    
    The station deletion is protected by synchronize_net(), but
    that isn't enough -- ieee80211_free_tid_rx() need not have
    run when that returns (it deletes the timer.) We could use
    rcu_barrier() instead of synchronize_net(), but that's much
    more expensive.
    
    Instead, to fix this, add a field tracking that the session
    is being deleted. In this case, the only re-arming of the
    timer happens with the reorder spinlock held, so make that
    code not rearm it if the session is being deleted and also
    delete the timer after setting that field. This ensures the
    timer cannot fire after ___ieee80211_stop_rx_ba_session()
    returns, which fixes the problem.
    
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
    788211d8
agg-rx.c 12.9 KB