]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
mac80211: fix RX A-MPDU session reorder timer deletion
authorJohannes Berg <johannes.berg@intel.com>
Wed, 1 Apr 2015 12:20:42 +0000 (14:20 +0200)
committerSasha Levin <sasha.levin@oracle.com>
Thu, 23 Apr 2015 18:58:29 +0000 (14:58 -0400)
commitf68391eb9bfd80cc898b07e71ed400d7e0c0f91a
tree8d49602d1baf42afa5f4eb30495ca39a438d7e07
parent4f33d5001b3e25e89e29277c85b954f9a2f75248
mac80211: fix RX A-MPDU session reorder timer deletion

[ Upstream commit 788211d81bfdf9b6a547d0530f206ba6ee76b107 ]

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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
net/mac80211/agg-rx.c
net/mac80211/rx.c
net/mac80211/sta_info.h