Message ID | 20210816134424.28191-1-pali@kernel.org (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | Johannes Berg |
Headers | show |
Series | mac80211: drop data frames without key on encrypted links | expand |
On Mon, Aug 16, 2021 at 03:44:24PM +0200, Pali Rohár wrote: > From: Johannes Berg <johannes.berg@intel.com> > > commit a0761a301746ec2d92d7fcb82af69c0a6a4339aa upstream. > > If we know that we have an encrypted link (based on having had > a key configured for TX in the past) then drop all data frames > in the key selection handler if there's no key anymore. > > This fixes an issue with mac80211 internal TXQs - there we can > buffer frames for an encrypted link, but then if the key is no > longer there when they're dequeued, the frames are sent without > encryption. This happens if a station is disconnected while the > frames are still on the TXQ. > > Detecting that a link should be encrypted based on a first key > having been configured for TX is fine as there are no use cases > for a connection going from with encryption to no encryption. > With extended key IDs, however, there is a case of having a key > configured for only decryption, so we can't just trigger this > behaviour on a key being configured. > > Cc: stable@vger.kernel.org > Reported-by: Jouni Malinen <j@w1.fi> > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > Signed-off-by: Luca Coelho <luciano.coelho@intel.com> > Link: https://lore.kernel.org/r/iwlwifi.20200326150855.6865c7f28a14.I9fb1d911b064262d33e33dfba730cdeef83926ca@changeid > Signed-off-by: Johannes Berg <johannes.berg@intel.com> > [pali: Backported to 4.19 and older versions] > Signed-off-by: Pali Rohár <pali@kernel.org> Now queued up, thanks! Did not apply to 4.4.y, don't know if you want it there or not... thanks, greg k-h
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 4105081dc1df..6f390c2e4c8e 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -80,6 +80,7 @@ static const char * const sta_flag_names[] = { FLAG(MPSP_OWNER), FLAG(MPSP_RECIPIENT), FLAG(PS_DELIVER), + FLAG(USES_ENCRYPTION), #undef FLAG }; diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 6775d6cb7d3d..7fc55177db84 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -341,6 +341,7 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, if (sta) { if (pairwise) { rcu_assign_pointer(sta->ptk[idx], new); + set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION); sta->ptk_idx = idx; ieee80211_check_fast_xmit(sta); } else { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index c33bc5fc0f2d..75d982ff7f3d 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -102,6 +102,7 @@ enum ieee80211_sta_info_flags { WLAN_STA_MPSP_OWNER, WLAN_STA_MPSP_RECIPIENT, WLAN_STA_PS_DELIVER, + WLAN_STA_USES_ENCRYPTION, NUM_WLAN_STA_FLAGS, }; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 98d048630ad2..3530d1a5fc98 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -593,10 +593,13 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; - if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) + if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) { tx->key = NULL; - else if (tx->sta && - (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx]))) + return TX_CONTINUE; + } + + if (tx->sta && + (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx]))) tx->key = key; else if (ieee80211_is_group_privacy_action(tx->skb) && (key = rcu_dereference(tx->sdata->default_multicast_key))) @@ -657,6 +660,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) if (!skip_hw && tx->key && tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) info->control.hw_key = &tx->key->conf; + } else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta && + test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) { + return TX_DROP; } return TX_CONTINUE;