Skip to content

Commit c3944a5

Browse files
Sriram Rjmberg-intel
authored andcommitted
ath11k: Clear the fragment cache during key install
Currently the fragment cache setup during peer assoc is cleared only during peer delete. In case a key reinstallation happens with the same peer, the same fragment cache with old fragments added before key installation could be clubbed with fragments received after. This might be exploited to mix fragments of different data resulting in a proper unintended reassembled packet to be passed up the stack. Hence flush the fragment cache on every key installation to prevent potential attacks (CVE-2020-24587). Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2 Cc: [email protected] Signed-off-by: Sriram R <[email protected]> Signed-off-by: Jouni Malinen <[email protected]> Link: https://lore.kernel.org/r/20210511200110.218dc777836f.I9af6fc76215a35936c4152552018afb5079c5d8c@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent 62a8ff6 commit c3944a5

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

drivers/net/wireless/ath/ath11k/dp_rx.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,24 @@ static void ath11k_dp_rx_frags_cleanup(struct dp_rx_tid *rx_tid, bool rel_link_d
852852
__skb_queue_purge(&rx_tid->rx_frags);
853853
}
854854

855+
void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer)
856+
{
857+
struct dp_rx_tid *rx_tid;
858+
int i;
859+
860+
lockdep_assert_held(&ar->ab->base_lock);
861+
862+
for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
863+
rx_tid = &peer->rx_tid[i];
864+
865+
spin_unlock_bh(&ar->ab->base_lock);
866+
del_timer_sync(&rx_tid->frag_timer);
867+
spin_lock_bh(&ar->ab->base_lock);
868+
869+
ath11k_dp_rx_frags_cleanup(rx_tid, true);
870+
}
871+
}
872+
855873
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer)
856874
{
857875
struct dp_rx_tid *rx_tid;

drivers/net/wireless/ath/ath11k/dp_rx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif,
4949
const u8 *peer_addr,
5050
enum set_key_cmd key_cmd,
5151
struct ieee80211_key_conf *key);
52+
void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer);
5253
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer);
5354
void ath11k_peer_rx_tid_delete(struct ath11k *ar,
5455
struct ath11k_peer *peer, u8 tid);

drivers/net/wireless/ath/ath11k/mac.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,6 +2779,12 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
27792779
*/
27802780
spin_lock_bh(&ab->base_lock);
27812781
peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
2782+
2783+
/* flush the fragments cache during key (re)install to
2784+
* ensure all frags in the new frag list belong to the same key.
2785+
*/
2786+
if (peer && cmd == SET_KEY)
2787+
ath11k_peer_frags_flush(ar, peer);
27822788
spin_unlock_bh(&ab->base_lock);
27832789

27842790
if (!peer) {

0 commit comments

Comments
 (0)