summaryrefslogtreecommitdiff
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2023-06-22 20:09:13 -0700
committerJakub Kicinski <kuba@kernel.org>2023-06-22 20:09:13 -0700
commite6988447c15d622d11c68250a33f47b3cacb66eb (patch)
tree5610d8905b548ff5afd38377b711c50a636b97a5 /net/mac80211/rx.c
parent08eeccb2491a3198f4adcba63adeace6e2499ea3 (diff)
parent31b5a547622b3782388eb676081da1eefe5b98d2 (diff)
Merge tag 'wireless-next-2023-06-22' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next
Johannes Berg says: ==================== Notable changes this time around: MAINTAINERS - add missing driver git trees ath11k - factory test mode support iwlwifi - config rework to drop test devices and split the different families - major update for new firmware and MLO stack - initial multi-link reconfiguration suppor - multi-BSSID and MLO improvements other - fix the last few W=1 warnings from GCC 13 - merged wireless tree to avoid conflicts * tag 'wireless-next-2023-06-22' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (245 commits) wifi: ieee80211: fix erroneous NSTR bitmap size checks wifi: rtlwifi: cleanup USB interface wifi: rtlwifi: simplify LED management wifi: ath10k: improve structure padding wifi: ath9k: convert msecs to jiffies where needed wifi: iwlwifi: mvm: Add support for IGTK in D3 resume flow wifi: iwlwifi: mvm: update two most recent GTKs on D3 resume flow wifi: iwlwifi: mvm: Refactor security key update after D3 wifi: mac80211: mark keys as uploaded when added by the driver wifi: iwlwifi: remove support of A0 version of FM RF wifi: iwlwifi: cfg: clean up Bz module firmware lines wifi: iwlwifi: pcie: add device id 51F1 for killer 1675 wifi: iwlwifi: bump FW API to 83 for AX/BZ/SC devices wifi: iwlwifi: cfg: remove trailing dash from FW_PRE constants wifi: iwlwifi: also unify Ma device configurations wifi: iwlwifi: also unify Sc device configurations wifi: iwlwifi: unify Bz/Gl device configurations wifi: iwlwifi: pcie: also drop jacket from info macro wifi: iwlwifi: remove support for *nJ devices wifi: iwlwifi: don't load old firmware for 22000 ... ==================== Link: https://lore.kernel.org/r/20230622185602.147650-2-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e2a973309bf7..4f707d2a160f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -6,7 +6,7 @@
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2022 Intel Corporation
+ * Copyright (C) 2018-2023 Intel Corporation
*/
#include <linux/jiffies.h>
@@ -1732,7 +1732,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
link_sta->rx_stats.last_rx = jiffies;
- if (ieee80211_is_data(hdr->frame_control) &&
+ if (ieee80211_is_data_present(hdr->frame_control) &&
!is_multicast_ether_addr(hdr->addr1))
link_sta->rx_stats.last_rate =
sta_stats_encode_rate(status);
@@ -1746,7 +1746,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
* match the current local configuration when processed.
*/
link_sta->rx_stats.last_rx = jiffies;
- if (ieee80211_is_data(hdr->frame_control))
+ if (ieee80211_is_data_present(hdr->frame_control))
link_sta->rx_stats.last_rate = sta_stats_encode_rate(status);
}
@@ -2405,9 +2405,9 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
- __le16 fc = hdr->frame_control;
+ struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
+ __le16 fc = mgmt->frame_control;
/*
* Pass through unencrypted frames if the hardware has
@@ -2416,15 +2416,27 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
if (status->flag & RX_FLAG_DECRYPTED)
return 0;
+ /* drop unicast protected dual (that wasn't protected) */
+ if (ieee80211_is_action(fc) &&
+ mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION)
+ return -EACCES;
+
if (rx->sta && test_sta_flag(rx->sta, WLAN_STA_MFP)) {
if (unlikely(!ieee80211_has_protected(fc) &&
- ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
- rx->key)) {
+ ieee80211_is_unicast_robust_mgmt_frame(rx->skb))) {
if (ieee80211_is_deauth(fc) ||
- ieee80211_is_disassoc(fc))
+ ieee80211_is_disassoc(fc)) {
+ /*
+ * Permit unprotected deauth/disassoc frames
+ * during 4-way-HS (key is installed after HS).
+ */
+ if (!rx->key)
+ return 0;
+
cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
rx->skb->data,
rx->skb->len);
+ }
return -EACCES;
}
/* BIP does not use Protected field, so need to check MMIE */
@@ -2451,6 +2463,12 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
if (unlikely(ieee80211_is_action(fc) && !rx->key &&
ieee80211_is_robust_mgmt_frame(rx->skb)))
return -EACCES;
+
+ /* drop unicast public action frames when using MPF */
+ if (is_unicast_ether_addr(mgmt->da) &&
+ ieee80211_is_public_action((void *)rx->skb->data,
+ rx->skb->len))
+ return -EACCES;
}
return 0;
@@ -2505,7 +2523,7 @@ bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata,
if (ether_addr_equal(sdata->vif.addr, addr))
return true;
- if (!sdata->vif.valid_links)
+ if (!ieee80211_vif_is_mld(&sdata->vif))
return false;
for (link_id = 0; link_id < ARRAY_SIZE(sdata->vif.link_conf); link_id++) {
@@ -3356,6 +3374,11 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
if (!ieee80211_is_mgmt(mgmt->frame_control))
return RX_DROP_MONITOR;
+ /* drop too small action frames */
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
+ return RX_DROP_UNUSABLE;
+
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
ieee80211_is_beacon(mgmt->frame_control) &&
!(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
@@ -3445,10 +3468,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (!ieee80211_is_action(mgmt->frame_control))
return RX_CONTINUE;
- /* drop too small frames */
- if (len < IEEE80211_MIN_ACTION_SIZE)
- return RX_DROP_UNUSABLE;
-
if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED &&
mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)