* [PATCH iwlwifi-next 02/15] wifi: iwlwifi: mld: validate WoWLAN notif header
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715190431.327910-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Validate fixed wowlan_info_notif header size first.
Only then read num_mlo_link_keys from pkt->data.
Apply this to v5 and v6 parsing paths.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mld/d3.c | 57 ++++++++++++++-------
1 file changed, 38 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
index b5fed6090340..c9c0e3c729c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c
@@ -573,18 +573,42 @@ iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5,
}
}
-static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld,
- u32 len,
- u32 expected_len,
- u8 num_mlo_keys,
+static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld, u32 len,
+ const void *notif_data,
int version)
{
u32 len_with_mlo_keys;
+ u32 expected_len;
+ u8 num_mlo_keys;
- if (IWL_FW_CHECK(mld, len < expected_len,
- "Invalid wowlan_info_notif v%d (expected=%u got=%u)\n",
- version, expected_len, len))
+ /* Extract num_mlo_keys from the void pointer based on version */
+ if (version == 5) {
+ const struct iwl_wowlan_info_notif_v5 *notif_v5 = notif_data;
+
+ expected_len = sizeof(*notif_v5);
+
+ if (IWL_FW_CHECK(mld, len < expected_len,
+ "Invalid wowlan_info_notif v5 (expected=%u got=%u)\n",
+ expected_len, len))
+ return false;
+
+ num_mlo_keys = notif_v5->num_mlo_link_keys;
+ } else if (version == 6) {
+ const struct iwl_wowlan_info_notif *notif = notif_data;
+
+ expected_len = sizeof(*notif);
+
+ if (IWL_FW_CHECK(mld, len < expected_len,
+ "Invalid wowlan_info_notif v6 (expected=%u got=%u)\n",
+ expected_len, len))
+ return false;
+
+ num_mlo_keys = notif->num_mlo_link_keys;
+ } else {
+ IWL_WARN(mld, "Unsupported wowlan_info_notif version %d\n",
+ version);
return false;
+ }
len_with_mlo_keys = expected_len +
(num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk));
@@ -616,16 +640,14 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
if (wowlan_info_ver == 5) {
/* v5 format - validate before conversion */
- const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data;
+ const struct iwl_wowlan_info_notif_v5 *_notif =
+ (void *)pkt->data;
- if (!iwl_mld_validate_wowlan_notif_size(mld, len,
- sizeof(*notif_v5),
- notif_v5->num_mlo_link_keys,
- 5))
+ if (!iwl_mld_validate_wowlan_notif_size(mld, len, _notif, 5))
return true;
converted_notif = kzalloc_flex(*converted_notif, mlo_gtks,
- notif_v5->num_mlo_link_keys,
+ _notif->num_mlo_link_keys,
GFP_ATOMIC);
if (!converted_notif) {
IWL_ERR(mld,
@@ -633,15 +655,12 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
return true;
}
- iwl_mld_convert_wowlan_notif_v5(notif_v5,
- converted_notif);
+ iwl_mld_convert_wowlan_notif_v5(_notif, converted_notif);
notif = converted_notif;
} else if (wowlan_info_ver == 6) {
notif = (void *)pkt->data;
- if (!iwl_mld_validate_wowlan_notif_size(mld, len,
- sizeof(*notif),
- notif->num_mlo_link_keys,
- 6))
+
+ if (!iwl_mld_validate_wowlan_notif_size(mld, len, notif, 6))
return true;
} else {
/* smaller versions are not supported */
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-next 00/15] wifi: iwlwifi: updates - 07-15-2026
From: Miri Korenblit @ 2026-07-15 19:04 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
Hi,
Cleanups, features, and fixes from our internal tree.
Thanks,
Miri
Avraham Stern (4):
wifi: iwlwifi: mld: support aborting an ongoing ftm request
wifi: iwlwifi: mei: check SAP message length before reading it
wifi: iwlwifi: mei: skip data read if length is too short
wifi: iwlwifi: mei: pass correct argument to function
Emmanuel Grumbach (5):
wifi: iwlwifi: mld: validate WoWLAN notif header
wifi: iwlwifi: fix counter type in iwl_fwrt_dump_error_logs
wifi: iwlwifi: mld: fix validation fallback in iwl_mld_notif_is_valid
wifi: iwlwifi: mvm: fix off-by-one in TXF key sanitiser
wifi: iwlwifi: guard against division by zero in
iwl_dbg_tlv_alloc_fragments
Ilan Peer (1):
wifi: iwlwifi: mld: Do not cleanup FW state when the device is dead
Johannes Berg (1):
wifi: iwlwifi: mvm/mld: fix PPE threshold debug print loop
Miri Korenblit (1):
wifi: iwlwifi: mld: add PNVM_INIT_COMPLETE_NTFY to the hcmd names
Pagadala Yesu Anjaneyulu (2):
wifi: iwlwifi: mld: honor FW puncturing capability in MCC response
wifi: iwlwifi: mvm: add LARI_CONFIG_EXTENSION command
Shahar Tzarfati (1):
wifi: iwlwifi: mld: fix read in wake packet notification handler
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 26 ++++++++
drivers/net/wireless/intel/iwlwifi/fw/dump.c | 2 +-
.../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 8 ++-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 30 +++++++++-
.../wireless/intel/iwlwifi/iwl-nvm-parse.h | 22 ++++++-
drivers/net/wireless/intel/iwlwifi/mei/main.c | 28 ++++++---
drivers/net/wireless/intel/iwlwifi/mld/d3.c | 60 ++++++++++++-------
.../intel/iwlwifi/mld/ftm-initiator.c | 21 +++++++
.../intel/iwlwifi/mld/ftm-initiator.h | 1 +
.../net/wireless/intel/iwlwifi/mld/mac80211.c | 16 ++++-
drivers/net/wireless/intel/iwlwifi/mld/mcc.c | 24 +++++---
drivers/net/wireless/intel/iwlwifi/mld/mld.c | 1 +
.../net/wireless/intel/iwlwifi/mld/notif.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mld/sta.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 36 +++++++++++
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 7 +--
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 +-
17 files changed, 242 insertions(+), 50 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH iwlwifi-fixes 15/15] wifi: iwlwifi: adapt ND match notif sizing to fixed matches array
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Switch iwl_scan_offload_match_info::matches to a fixed-size array and
adjust D3 netdetect size handling accordingly.
In MVM D3 paths, compute expected payload size as
offsetof(struct iwl_scan_offload_match_info, matches) + matches_len to
preserve previous behavior after the struct layout change.
In MLD D3 netdetect handling, keep the simple full-notification size
assumption and validate against sizeof(*notif) before accessing data.
This keeps scan offload / netdetect functionality unchanged while
making length checks consistent with the new struct definition.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/api/scan.h | 4 ++--
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 9 ++++++---
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
index 08f4cc3ea1c3..ee78371082b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018-2025 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2026 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -1319,7 +1319,7 @@ struct iwl_scan_offload_match_info {
u8 resume_while_scanning;
u8 self_recovery;
__le16 reserved;
- struct iwl_scan_offload_profile_match matches[];
+ struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES_V2];
} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_3 and
* SCAN_OFFLOAD_MATCH_INFO_NOTIFICATION_S_VER_1
*/
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 109265149963..6b11fa32ea5c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -2459,13 +2459,15 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
if (fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
- query_len = sizeof(struct iwl_scan_offload_match_info);
matches_len = sizeof(struct iwl_scan_offload_profile_match) *
max_profiles;
+ query_len = offsetof(struct iwl_scan_offload_match_info,
+ matches) + matches_len;
} else {
- query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
max_profiles;
+ query_len = sizeof(struct iwl_scan_offload_profiles_query_v1) +
+ matches_len;
}
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
@@ -2819,7 +2821,8 @@ static void iwl_mvm_nd_match_info_handler(struct iwl_mvm *mvm,
if (IS_ERR_OR_NULL(vif))
return;
- if (len < sizeof(struct iwl_scan_offload_match_info) + matches_len) {
+ if (len < offsetof(struct iwl_scan_offload_match_info, matches) +
+ matches_len) {
IWL_ERR(mvm, "Invalid scan match info notification\n");
return;
}
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 14/15] wifi: iwlwifi: mvm: fix a possible underflow
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
We shouldn't trust the firmware about the length of the wowlan packet.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 4eaba0bc4a1e..109265149963 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1509,6 +1509,10 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
if (WARN_ON_ONCE(truncated < 0))
truncated = 0;
+ /* this would be a firmware bug */
+ if (WARN_ON_ONCE(pktsize < sizeof(*hdr)))
+ return;
+
if (ieee80211_is_data(hdr->frame_control)) {
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
int ivlen = 0, icvlen = 4; /* also FCS */
@@ -1517,10 +1521,6 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
if (!pkt)
goto report;
- skb_put_data(pkt, pktdata, hdrlen);
- pktdata += hdrlen;
- pktsize -= hdrlen;
-
if (ieee80211_has_protected(hdr->frame_control)) {
/*
* This is unlocked and using gtk_i(c)vlen,
@@ -1546,6 +1546,17 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
truncated = 0;
}
+ if (IWL_FW_CHECK(mvm,
+ pktsize <= hdrlen + ivlen + icvlen,
+ "pktsize is too small %d\n",
+ pktsize)) {
+ kfree_skb(pkt);
+ return;
+ }
+
+ skb_put_data(pkt, pktdata, hdrlen);
+ pktdata += hdrlen;
+ pktsize -= hdrlen;
pktsize -= ivlen + icvlen;
pktdata += ivlen;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 13/15] wifi: iwlwifi: mvm: copy the correct TK length for ranging
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Avraham Stern <avraham.stern@intel.com>
When setting the TK for ranging with an associated peer, 32 bytes of
TK are copied from the vif key without verifying the actual key length
which may be only 16 bytes if CCMP-128 is used. Fix it by setting the
copy length according to the key cipher.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
.../intel/iwlwifi/mvm/ftm-initiator.c | 55 +++++++++++++------
1 file changed, 38 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
index 3a14ca5e512a..8d7f60dcd027 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
@@ -646,7 +646,8 @@ static void iter(struct ieee80211_hw *hw,
WARN_ON(*target->cipher == IWL_LOCATION_CIPHER_INVALID);
}
-static void
+/* The tk buffer is assumed to be exactly TK_11AZ_LEN bytes */
+static int
iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
u8 *bssid, u8 *cipher, u8 *hltk, u8 *tk,
u8 *rx_pn, u8 *tx_pn, __le32 *flags)
@@ -656,12 +657,12 @@ iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (mvmvif->ftm_unprotected)
- return;
+ return 0;
#endif
if (!(le32_to_cpu(*flags) & (IWL_INITIATOR_AP_FLAGS_NON_TB |
IWL_INITIATOR_AP_FLAGS_TB)))
- return;
+ return 0;
lockdep_assert_held(&mvm->mutex);
@@ -679,14 +680,31 @@ iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (vif->cfg.assoc &&
!memcmp(vif->bss_conf.bssid, bssid, ETH_ALEN)) {
struct iwl_mvm_ftm_iter_data target;
+ u32 key_len;
target.bssid = bssid;
target.cipher = cipher;
target.tk = NULL;
ieee80211_iter_keys(mvm->hw, vif, iter, &target);
- if (!WARN_ON(!target.tk))
- memcpy(tk, target.tk, TK_11AZ_LEN);
+ if (WARN_ON(!target.tk))
+ return -EINVAL;
+
+ switch (*target.cipher) {
+ case IWL_LOCATION_CIPHER_CCMP_128:
+ case IWL_LOCATION_CIPHER_GCMP_128:
+ key_len = WLAN_KEY_LEN_CCMP;
+ break;
+ case IWL_LOCATION_CIPHER_GCMP_256:
+ key_len = WLAN_KEY_LEN_GCMP_256;
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ memset(tk, 0, TK_11AZ_LEN);
+ memcpy(tk, target.tk, key_len);
} else {
memcpy(tk, entry->tk, sizeof(entry->tk));
}
@@ -695,8 +713,10 @@ iwl_mvm_ftm_set_secured_ranging(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
memcpy(tx_pn, entry->tx_pn, sizeof(entry->tx_pn));
FTM_SET_FLAG(SECURED);
- return;
+ return 0;
}
+
+ return 0;
}
static int
@@ -708,12 +728,11 @@ iwl_mvm_ftm_put_target_v7(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (err)
return err;
- iwl_mvm_ftm_set_secured_ranging(mvm, vif, target->bssid,
- &target->cipher, target->hltk,
- target->tk, target->rx_pn,
- target->tx_pn,
- &target->initiator_ap_flags);
- return err;
+ return iwl_mvm_ftm_set_secured_ranging(mvm, vif, target->bssid,
+ &target->cipher, target->hltk,
+ target->tk, target->rx_pn,
+ target->tx_pn,
+ &target->initiator_ap_flags);
}
static int iwl_mvm_ftm_start_v11(struct iwl_mvm *mvm,
@@ -881,11 +900,13 @@ iwl_mvm_ftm_put_target_v10(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_ftm_set_target_flags(mvm, peer, &target->initiator_ap_flags);
iwl_mvm_ftm_set_sta(mvm, vif, peer, &target->sta_id,
&target->initiator_ap_flags);
- iwl_mvm_ftm_set_secured_ranging(mvm, vif, target->bssid,
- &target->cipher, target->hltk,
- target->tk, target->rx_pn,
- target->tx_pn,
- &target->initiator_ap_flags);
+ ret = iwl_mvm_ftm_set_secured_ranging(mvm, vif, target->bssid,
+ &target->cipher, target->hltk,
+ target->tk, target->rx_pn,
+ target->tx_pn,
+ &target->initiator_ap_flags);
+ if (ret)
+ return ret;
i2r_max_sts = IWL_MVM_FTM_I2R_MAX_STS > 1 ? 1 :
IWL_MVM_FTM_I2R_MAX_STS;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 12/15] wifi: iwlwifi: mvm: add a check on the tid coming from the firmware
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
ba_notif->tid is a firmware-controlled u8 that is used directly
as an array index into tid_data[] without any validation. Add a
bounds check against IWL_MAX_TID_COUNT before dereferencing the
array.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index e02c376296c4..d3c2fe830477 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -2161,6 +2161,9 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
ba_notif = (void *)pkt->data;
sta_id = ba_notif->sta_id;
tid = ba_notif->tid;
+ if (IWL_FW_CHECK(mvm, tid >= ARRAY_SIZE(mvmsta->tid_data),
+ "invalid TID %d in BA notif\n", tid))
+ return;
/* "flow" corresponds to Tx queue */
txq = le16_to_cpu(ba_notif->scd_flow);
/* "ssn" is start of block-ack Tx window, corresponds to index
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 11/15] wifi: iwlwifi: mvm: fix out-of-bounds tid_data access in BA notif
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
mvmsta->tid_data was indexed by the TFD loop counter 'i' instead of
the actual TID value 'tid'. This writes lq_color into a random tid_data
slot unrelated to the BA entry.
Since multi-TID blockack is not really in use, 'i' was always 0 and no
harm was done.
Add a out-of-bound check before accessing the array.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index d8b088e7c250..e02c376296c4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -2134,8 +2134,14 @@ void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
if (tid == IWL_MGMT_TID)
tid = IWL_MAX_TID_COUNT;
+ if (IWL_FW_CHECK(mvm, tid >=
+ ARRAY_SIZE(mvmsta->tid_data),
+ "invalid TID %d in compressed BA\n",
+ tid))
+ continue;
+
if (mvmsta)
- mvmsta->tid_data[i].lq_color = lq_color;
+ mvmsta->tid_data[tid].lq_color = lq_color;
iwl_mvm_tx_reclaim(mvm, sta_id, tid,
(int)(le16_to_cpu(ba_tfd->q_num)),
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 10/15] wifi: iwlwifi: pcie: validate FW section counts in iwl_pcie_init_fw_sec
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
iwl_pcie_init_fw_sec() iterates over LMAC, UMAC, and paging
firmware sections and writes to ctxt_dram->lmac_img[i],
ctxt_dram->umac_img[i], and ctxt_dram->virtual_img[i] without
first verifying that the counts derived from the firmware image
do not exceed the array size. An oversized firmware image could
cause out-of-bounds writes into the fixed-size context-info DRAM
arrays.
Add explicit WARN_ON checks for all three section counts and
return -EINVAL if any is exceeded.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
index d5eb895144ef..7f886200d693 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2025 Intel Corporation
+ * Copyright (C) 2018-2026 Intel Corporation
*/
#include "iwl-trans.h"
#include "iwl-fh.h"
@@ -99,6 +99,11 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
/* add 2 due to separators */
paging_cnt = iwl_pcie_get_num_sections(fw, lmac_cnt + umac_cnt + 2);
+ if (WARN_ON(lmac_cnt > ARRAY_SIZE(ctxt_dram->lmac_img) ||
+ umac_cnt > ARRAY_SIZE(ctxt_dram->umac_img) ||
+ paging_cnt > ARRAY_SIZE(ctxt_dram->virtual_img)))
+ return -EINVAL;
+
dram->fw = kzalloc_objs(*dram->fw, umac_cnt + lmac_cnt);
if (!dram->fw)
return -ENOMEM;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 09/15] wifi: iwlwifi: mvm: ptp: free response on success path
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Release CMD_WANT_SKB response buffer after successful timestamp parsing
to avoid leaking response allocations.
Assisted-by: GitHubCopilot:GPT-5.3-Codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/ptp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c b/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
index f39eb48864eb..49dcb1388007 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2021 - 2023, 2025 Intel Corporation
+ * Copyright (C) 2021 - 2023, 2025-2026 Intel Corporation
*/
#include "mvm.h"
@@ -121,6 +121,8 @@ iwl_mvm_get_crosstimestamp_fw(struct iwl_mvm *mvm, u32 *gp2, u64 *sys_time)
*sys_time = (u64)le32_to_cpu(resp->platform_timestamp_hi) << 32 |
le32_to_cpu(resp->platform_timestamp_lo);
+ iwl_free_resp(&cmd);
+
return ret;
}
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 08/15] wifi: iwlwifi: mvm: fix read in wake packet notification handler
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shahar Tzarfati
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Shahar Tzarfati <shahar.tzarfati@intel.com>
In iwl_mvm_wowlan_store_wake_pkt(), packet_len was initialized from
notif->wake_packet_length before the explicit check that len >=
sizeof(*notif).
Move the assignment of packet_len to after the size check so that
notif->wake_packet_length is only accessed once the payload length
has been validated.
Fixes: 219ed58feda9 ("wifi: iwlwifi: mvm: Add support for wowlan wake packet notification")
Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 3429d9a10e42..4eaba0bc4a1e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -2756,7 +2756,7 @@ static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm *mvm,
struct iwl_wowlan_status_data *status,
u32 len)
{
- u32 data_size, packet_len = le32_to_cpu(notif->wake_packet_length);
+ u32 data_size, packet_len;
if (len < sizeof(*notif)) {
IWL_ERR(mvm, "Invalid WoWLAN wake packet notification!\n");
@@ -2775,6 +2775,7 @@ static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm *mvm,
return -EIO;
}
+ packet_len = le32_to_cpu(notif->wake_packet_length);
data_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet);
/* data_size got the padding from the notification, remove it. */
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 07/15] wifi: iwlwifi: validate payload length in iwl_pnvm_complete_fn
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
iwl_pnvm_complete_fn() casts pkt->data directly to
struct iwl_pnvm_init_complete_ntfy and reads the status field
without first verifying that the firmware notification payload
is large enough to contain that structure.
Add a WARN_ON_ONCE check against sizeof(*pnvm_ntf) and return
early without reading uninitialised memory if the payload is too
short.
Fixes: b3e4c0f34c17 ("iwlwifi: move PNVM implementation to common code")
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index afff8d51ca95..ec0ff58ab312 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright(c) 2020-2025 Intel Corporation
+ * Copyright(c) 2020-2026 Intel Corporation
*/
#include "iwl-drv.h"
@@ -12,6 +12,7 @@
#include "fw/api/alive.h"
#include "fw/uefi.h"
#include "fw/img.h"
+#include "fw/dbg.h"
#define IWL_PNVM_REDUCED_CAP_BIT BIT(25)
@@ -26,6 +27,12 @@ static bool iwl_pnvm_complete_fn(struct iwl_notif_wait_data *notif_wait,
struct iwl_trans *trans = (struct iwl_trans *)data;
struct iwl_pnvm_init_complete_ntfy *pnvm_ntf = (void *)pkt->data;
+ if (IWL_FW_CHECK(trans,
+ iwl_rx_packet_payload_len(pkt) < sizeof(*pnvm_ntf),
+ "Bad notif len: %d\n",
+ iwl_rx_packet_payload_len(pkt)))
+ return true;
+
IWL_DEBUG_FW(trans,
"PNVM complete notification received with status 0x%0x\n",
le32_to_cpu(pnvm_ntf->status));
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 06/15] wifi: iwlwifi: fix pointer arithmetic in iwl_add_mcc_to_tas_block_list
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
The expression list[*size++] increments the pointer 'size'
rather than the u8 value it points to (operator precedence: ++
binds to the pointer before the dereference). As a result the
block-list entry is written at the correct index but *size is
never incremented, so the caller's count stays at zero and
subsequent calls overwrite slot 0 every time.
Change to list[(*size)++] so that the value pointed to by size
is incremented after use as the array index.
Fixes: 5f4656610edb ("wifi: iwlwifi: extend TAS_CONFIG cmd support for v5")
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/regulatory.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
index 8d9ff36e30f5..1d6d38ee55b4 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/regulatory.c
@@ -389,7 +389,7 @@ bool iwl_add_mcc_to_tas_block_list(u16 *list, u8 *size, u16 mcc)
if (*size >= IWL_WTAS_BLACK_LIST_MAX)
return false;
- list[*size++] = mcc;
+ list[(*size)++] = mcc;
return true;
}
IWL_EXPORT_SYMBOL(iwl_add_mcc_to_tas_block_list);
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 05/15] wifi: iwlwifi: fw: validate SMEM response size
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shahar Tzarfati, Johannes Berg
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Shahar Tzarfati <shahar.tzarfati@intel.com>
The SMEM parsers cast firmware response payloads directly to shared
memory configuration structures. A short response can leave fields
outside the received payload while the driver still dereferences them.
Check the response payload length before reading the base fields in
both parser variants. Require the full legacy extended layout before
reading internal TX FIFO data. Valid responses keep the same parsed
values.
Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/smem.c | 28 ++++++++++++++++----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c
index 344ddde85b18..20ed26a1bb00 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2021, 2025 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2021, 2025-2026 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -14,9 +14,17 @@ static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt,
{
struct iwl_shared_mem_cfg *mem_cfg = (void *)pkt->data;
int i, lmac;
- int lmac_num = le32_to_cpu(mem_cfg->lmac_num);
- u8 api_ver = iwl_fw_lookup_notif_ver(fwrt->fw, SYSTEM_GROUP,
- SHARED_MEM_CFG_CMD, 0);
+ int lmac_num;
+ u8 api_ver;
+
+ if (IWL_FW_CHECK(fwrt, iwl_rx_packet_payload_len(pkt) <
+ offsetofend(struct iwl_shared_mem_cfg, lmac_smem[1]),
+ "bad shared mem notification size\n"))
+ return;
+
+ lmac_num = le32_to_cpu(mem_cfg->lmac_num);
+ api_ver = iwl_fw_lookup_notif_ver(fwrt->fw, SYSTEM_GROUP,
+ SHARED_MEM_CFG_CMD, 0);
/* Note: notification has 3 entries, but we only expect 2 */
if (IWL_FW_CHECK(fwrt, lmac_num > ARRAY_SIZE(fwrt->smem_cfg.lmac),
@@ -30,7 +38,7 @@ static void iwl_parse_shared_mem_22000(struct iwl_fw_runtime *fwrt,
if (api_ver >= 4 &&
!IWL_FW_CHECK(fwrt, iwl_rx_packet_payload_len(pkt) < sizeof(*mem_cfg),
- "bad shared mem notification size\n")) {
+ "bad shared mem notification size (v4)\n")) {
fwrt->smem_cfg.rxfifo2_control_size =
le32_to_cpu(mem_cfg->rxfifo2_control_size);
}
@@ -53,6 +61,11 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
struct iwl_shared_mem_cfg_v2 *mem_cfg = (void *)pkt->data;
int i;
+ if (IWL_FW_CHECK(fwrt, iwl_rx_packet_payload_len(pkt) <
+ offsetof(struct iwl_shared_mem_cfg_v2, rxfifo_addr),
+ "bad shared mem notification size\n"))
+ return;
+
fwrt->smem_cfg.num_lmacs = 1;
fwrt->smem_cfg.num_txfifo_entries = ARRAY_SIZE(mem_cfg->txfifo_size);
@@ -67,6 +80,11 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
/* new API has more data, from rxfifo_addr field and on */
if (fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
+ if (IWL_FW_CHECK(fwrt, iwl_rx_packet_payload_len(pkt) <
+ sizeof(*mem_cfg),
+ "bad shared mem notification size (extend)\n"))
+ return;
+
BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) !=
sizeof(mem_cfg->internal_txfifo_size));
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 04/15] wifi: iwlwifi: mvm: validate SAR GEO response payload size
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Pagadala Yesu Anjaneyulu
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
The SAR GEO command response is cast to
iwl_geo_tx_power_profiles_resp without verifying the payload length.
A malformed or unexpected firmware response can lead to reading an
invalid structure layout.
Add an explicit size check before accessing the response data and
return -EIO when the payload size is wrong.
Fixes: f604324eefec ("iwlwifi: remove iwl_validate_sar_geo_profile() export")
Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 6e507d6dcdd2..fa523be91d8a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -964,12 +964,22 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
return ret;
}
+ if (IWL_FW_CHECK(mvm,
+ iwl_rx_packet_payload_len(cmd.resp_pkt) !=
+ sizeof(*resp),
+ "Wrong size for iwl_geo_tx_power_profiles_resp: %d\n",
+ iwl_rx_packet_payload_len(cmd.resp_pkt))) {
+ ret = -EIO;
+ goto out;
+ }
+
resp = (void *)cmd.resp_pkt->data;
ret = le32_to_cpu(resp->profile_idx);
if (WARN_ON(ret > BIOS_GEO_MAX_PROFILE_NUM))
ret = -EIO;
+out:
iwl_free_resp(&cmd);
return ret;
}
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 03/15] wifi: iwlwifi: mvm: validate TX_CMD response layout
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
TX_CMD parsing uses frame_count to walk status entries and then
read the trailing SCD SSN. Make the minimum-length check follow
that exact runtime layout calculation before parsing the payload.
For new TX API, reject TX_CMD responses with frame_count != 1 and
warn/return in the aggregation handler to document that aggregated
accounting is expected via BA notifications.
Assisted-by: GitHubCopilot:gpt-5.3-codex
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 34 +++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index dc69c71faa76..d8b088e7c250 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1544,6 +1544,17 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm *mvm,
return val & 0xFFF;
}
+static inline size_t iwl_mvm_tx_resp_min_len(struct iwl_mvm *mvm,
+ struct iwl_tx_resp *tx_resp)
+{
+ struct agg_tx_status *agg_status =
+ iwl_mvm_get_agg_status(mvm, tx_resp);
+
+ /* The aggregate response ends with a trailing SCD SSN __le32 word. */
+ return (u8 *)(agg_status + tx_resp->frame_count) - (u8 *)tx_resp +
+ sizeof(__le32);
+}
+
static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt)
{
@@ -1847,6 +1858,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
int queue = SEQ_TO_QUEUE(sequence);
struct ieee80211_sta *sta;
+ if (WARN_ON_ONCE(iwl_mvm_has_new_tx_api(mvm)))
+ return;
+
if (WARN_ON_ONCE(queue < IWL_MVM_DQA_MIN_DATA_QUEUE &&
(queue != IWL_MVM_DQA_BSS_CLIENT_QUEUE)))
return;
@@ -1881,6 +1895,26 @@ void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_tx_resp *tx_resp = (void *)pkt->data;
+ size_t min_len;
+
+ if (IWL_FW_CHECK(mvm, !tx_resp->frame_count,
+ "invalid TX_CMD frame_count %u\n",
+ tx_resp->frame_count))
+ return;
+
+ if (IWL_FW_CHECK(mvm,
+ iwl_mvm_has_new_tx_api(mvm) &&
+ tx_resp->frame_count != 1,
+ "invalid TX_CMD frame_count %u for new TX API\n",
+ tx_resp->frame_count))
+ return;
+
+ min_len = iwl_mvm_tx_resp_min_len(mvm, tx_resp);
+ if (IWL_FW_CHECK(mvm, iwl_rx_packet_payload_len(pkt) < min_len,
+ "invalid TX_CMD len %u (frame_count %u, min %zu)\n",
+ iwl_rx_packet_payload_len(pkt), tx_resp->frame_count,
+ min_len))
+ return;
if (tx_resp->frame_count == 1)
iwl_mvm_rx_tx_cmd_single(mvm, pkt);
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 02/15] wifi: iwlwifi: add support for additional channels in NVM_GET_INFO
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach, Johannes Berg
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
We need to expect more channels on devices that support UNII-9.
Since iwl_ext_nvm_channels and iwl_uhb_nvm_channels are just a prefix
of iwl_unii9_nvm_channels just use iwl_unii9_nvm_channels and modify the
number of channels if the device does not support UNII-9 channels.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
.../net/wireless/intel/iwlwifi/cfg/rf-pe.c | 1 +
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 33 +++++++++-
.../net/wireless/intel/iwlwifi/iwl-config.h | 2 +
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 64 ++++++++++++-------
4 files changed, 74 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
index 7a04cb120b1b..6080f5f23e69 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
@@ -15,6 +15,7 @@
.non_shared_ant = ANT_B, \
.vht_mu_mimo_supported = true, \
.uhb_supported = true, \
+ .unii9_supported = true, \
.eht_supported = true, \
.uhr_supported = true, \
.num_rbds = IWL_NUM_RBDS_EHT, \
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index 443a9a416325..0172c0747a47 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -205,6 +205,7 @@ struct iwl_nvm_get_info_phy {
#define IWL_NUM_CHANNELS_V1 51
#define IWL_NUM_CHANNELS_V2 110
+#define IWL_NUM_CHANNELS_V3 115
/**
* struct iwl_nvm_get_info_regulatory_v1 - regulatory information
@@ -219,12 +220,12 @@ struct iwl_nvm_get_info_regulatory_v1 {
} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
/**
- * struct iwl_nvm_get_info_regulatory - regulatory information
+ * struct iwl_nvm_get_info_regulatory_v2 - regulatory information
* @lar_enabled: is LAR enabled
* @n_channels: number of valid channels in the array
* @channel_profile: regulatory data of this channel
*/
-struct iwl_nvm_get_info_regulatory {
+struct iwl_nvm_get_info_regulatory_v2 {
__le32 lar_enabled;
__le32 n_channels;
__le32 channel_profile[IWL_NUM_CHANNELS_V2];
@@ -244,6 +245,32 @@ struct iwl_nvm_get_info_rsp_v3 {
struct iwl_nvm_get_info_regulatory_v1 regulatory;
} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
+/**
+ * struct iwl_nvm_get_info_rsp_v4 - response to get NVM data
+ * @general: general NVM data
+ * @mac_sku: data relating to MAC sku
+ * @phy_sku: data relating to PHY sku
+ * @regulatory: regulatory data
+ */
+struct iwl_nvm_get_info_rsp_v4 {
+ struct iwl_nvm_get_info_general general;
+ struct iwl_nvm_get_info_sku mac_sku;
+ struct iwl_nvm_get_info_phy phy_sku;
+ struct iwl_nvm_get_info_regulatory_v2 regulatory;
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4 */
+
+/**
+ * struct iwl_nvm_get_info_regulatory - regulatory information
+ * @lar_enabled: is LAR enabled
+ * @n_channels: number of valid channels in the array
+ * @channel_profile: regulatory data of this channel
+ */
+struct iwl_nvm_get_info_regulatory {
+ __le32 lar_enabled;
+ __le32 n_channels;
+ __le32 channel_profile[IWL_NUM_CHANNELS_V3];
+} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_3 */
+
/**
* struct iwl_nvm_get_info_rsp - response to get NVM data
* @general: general NVM data
@@ -256,7 +283,7 @@ struct iwl_nvm_get_info_rsp {
struct iwl_nvm_get_info_sku mac_sku;
struct iwl_nvm_get_info_phy phy_sku;
struct iwl_nvm_get_info_regulatory regulatory;
-} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4 */
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_5 */
/**
* struct iwl_nvm_access_complete_cmd - NVM_ACCESS commands are completed
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 6a3539ad7331..3ac7f000ede4 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -415,6 +415,7 @@ struct iwl_mac_cfg {
* @vht_mu_mimo_supported: VHT MU-MIMO support
* @nvm_type: see &enum iwl_nvm_type
* @uhb_supported: ultra high band channels supported
+ * @unii9_supported: UNII-9 channels supported
* @eht_supported: EHT supported
* @uhr_supported: UHR supported
* @num_rbds: number of receive buffer descriptors to use
@@ -450,6 +451,7 @@ struct iwl_rf_cfg {
lp_xtal_workaround:1,
vht_mu_mimo_supported:1,
uhb_supported:1,
+ unii9_supported:1,
eht_supported:1,
uhr_supported:1;
u8 valid_tx_ant;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index d47b4ae2f486..bd5353fdde81 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -85,16 +85,7 @@ static const u16 iwl_nvm_channels[] = {
149, 153, 157, 161, 165
};
-static const u16 iwl_ext_nvm_channels[] = {
- /* 2.4 GHz */
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- /* 5 GHz */
- 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
- 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
- 149, 153, 157, 161, 165, 169, 173, 177, 181
-};
-
-static const u16 iwl_uhb_nvm_channels[] = {
+static const u16 iwl_unii9_nvm_channels[] = {
/* 2.4 GHz */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
/* 5 GHz */
@@ -105,12 +96,16 @@ static const u16 iwl_uhb_nvm_channels[] = {
1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69,
73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129,
133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185,
- 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233
+ 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233,
+
+ /* UNII-9 */
+ 237, 241, 245, 249, 253
};
#define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
-#define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
-#define IWL_NVM_NUM_CHANNELS_UHB ARRAY_SIZE(iwl_uhb_nvm_channels)
+#define IWL_NVM_NUM_CHANNELS_EXT 51
+#define IWL_NVM_NUM_CHANNELS_UHB 110
+#define IWL_NVM_NUM_CHANNELS_UNII9 ARRAY_SIZE(iwl_unii9_nvm_channels)
#define NUM_2GHZ_CHANNELS 14
#define NUM_5GHZ_CHANNELS 37
#define FIRST_2GHZ_HT_MINUS 5
@@ -351,12 +346,15 @@ static int iwl_init_channel_map(struct iwl_trans *trans,
int num_of_ch;
const u16 *nvm_chan;
- if (cfg->uhb_supported) {
+ if (cfg->unii9_supported) {
+ num_of_ch = IWL_NVM_NUM_CHANNELS_UNII9;
+ nvm_chan = iwl_unii9_nvm_channels;
+ } else if (cfg->uhb_supported) {
num_of_ch = IWL_NVM_NUM_CHANNELS_UHB;
- nvm_chan = iwl_uhb_nvm_channels;
+ nvm_chan = iwl_unii9_nvm_channels;
} else if (cfg->nvm_type == IWL_NVM_EXT) {
num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
- nvm_chan = iwl_ext_nvm_channels;
+ nvm_chan = iwl_unii9_nvm_channels;
} else {
num_of_ch = IWL_NVM_NUM_CHANNELS;
nvm_chan = iwl_nvm_channels;
@@ -1441,7 +1439,9 @@ iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
u8 rx_chains = fw->valid_rx_ant;
u8 tx_chains = fw->valid_rx_ant;
- if (cfg->uhb_supported)
+ if (cfg->unii9_supported)
+ data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UNII9);
+ else if (cfg->uhb_supported)
data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UHB);
else
data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_EXT);
@@ -1506,7 +1506,9 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
u16 lar_config;
const __le16 *ch_section;
- if (cfg->uhb_supported)
+ if (cfg->unii9_supported)
+ data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UNII9);
+ else if (cfg->uhb_supported)
data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UHB);
else if (cfg->nvm_type != IWL_NVM_EXT)
data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS);
@@ -1727,12 +1729,15 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans,
int max_num_ch;
struct iwl_reg_capa reg_capa;
- if (cfg->uhb_supported) {
+ if (cfg->unii9_supported) {
+ max_num_ch = IWL_NVM_NUM_CHANNELS_UNII9;
+ nvm_chan = iwl_unii9_nvm_channels;
+ } else if (cfg->uhb_supported) {
max_num_ch = IWL_NVM_NUM_CHANNELS_UHB;
- nvm_chan = iwl_uhb_nvm_channels;
+ nvm_chan = iwl_unii9_nvm_channels;
} else if (cfg->nvm_type == IWL_NVM_EXT) {
max_num_ch = IWL_NVM_NUM_CHANNELS_EXT;
- nvm_chan = iwl_ext_nvm_channels;
+ nvm_chan = iwl_unii9_nvm_channels;
} else {
max_num_ch = IWL_NVM_NUM_CHANNELS;
nvm_chan = iwl_nvm_channels;
@@ -2087,13 +2092,26 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
struct iwl_nvm_get_info_rsp_v3 *rsp_v3;
bool v4 = fw_has_api(&fw->ucode_capa,
IWL_UCODE_TLV_API_REGULATORY_NVM_INFO);
- size_t rsp_size = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
+ size_t rsp_size;
void *channel_profile;
ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret)
return ERR_PTR(ret);
+ switch (iwl_fw_lookup_notif_ver(fw, REGULATORY_AND_NVM_GROUP,
+ NVM_GET_INFO, 0)) {
+ case 5:
+ rsp_size = sizeof(struct iwl_nvm_get_info_rsp);
+ break;
+ case 4:
+ rsp_size = sizeof(struct iwl_nvm_get_info_rsp_v4);
+ break;
+ default:
+ rsp_size = sizeof(struct iwl_nvm_get_info_rsp_v3);
+ break;
+ }
+
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != rsp_size,
"Invalid payload len in NVM response from FW %d",
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
@@ -2107,7 +2125,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
if (empty_otp)
IWL_INFO(trans, "OTP is empty\n");
- nvm = kzalloc_flex(*nvm, channels, IWL_NUM_CHANNELS_V2);
+ nvm = kzalloc_flex(*nvm, channels, IWL_NUM_CHANNELS_V3);
if (!nvm) {
ret = -ENOMEM;
goto out;
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 01/15] wifi: iwlwifi: mld: validate txq_id in TX response handler
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
In-Reply-To: <20260715185715.321797-1-miriam.rachel.korenblit@intel.com>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Validate txq_id from TX response notification before passing to
iwl_trans_reclaim(). Other reclaim paths in this file perform this
check to prevent out-of-bounds access on malformed notifications.
Assisted-by: GitHubCopilot:claude-haiku-4.5
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mld/tx.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index 2185dade95f8..2df6643a5aa8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -1120,6 +1120,10 @@ void iwl_mld_handle_tx_resp_notif(struct iwl_mld *mld,
ssn = le32_to_cpup((__le32 *)agg_status +
tx_resp->frame_count) & 0xFFFF;
+ if (IWL_FW_CHECK(mld, txq_id >= ARRAY_SIZE(mld->fw_id_to_txq),
+ "Invalid txq id %d\n", txq_id))
+ return;
+
__skb_queue_head_init(&skbs);
/* we can free until ssn % q.n_bd not inclusive */
--
2.34.1
^ permalink raw reply related
* [PATCH iwlwifi-fixes 00/15] wifi: iwlwifi: fixes - 07-15-2026
From: Miri Korenblit @ 2026-07-15 18:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless
bugfixes...
Avraham Stern (1):
wifi: iwlwifi: mvm: copy the correct TK length for ranging
Emmanuel Grumbach (11):
wifi: iwlwifi: mld: validate txq_id in TX response handler
wifi: iwlwifi: add support for additional channels in NVM_GET_INFO
wifi: iwlwifi: mvm: validate TX_CMD response layout
wifi: iwlwifi: fix pointer arithmetic in iwl_add_mcc_to_tas_block_list
wifi: iwlwifi: validate payload length in iwl_pnvm_complete_fn
wifi: iwlwifi: mvm: ptp: free response on success path
wifi: iwlwifi: pcie: validate FW section counts in
iwl_pcie_init_fw_sec
wifi: iwlwifi: mvm: fix out-of-bounds tid_data access in BA notif
wifi: iwlwifi: mvm: add a check on the tid coming from the firmware
wifi: iwlwifi: mvm: fix a possible underflow
wifi: iwlwifi: adapt ND match notif sizing to fixed matches array
Pagadala Yesu Anjaneyulu (1):
wifi: iwlwifi: mvm: validate SAR GEO response payload size
Shahar Tzarfati (2):
wifi: iwlwifi: fw: validate SMEM response size
wifi: iwlwifi: mvm: fix read in wake packet notification handler
.../net/wireless/intel/iwlwifi/cfg/rf-pe.c | 1 +
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 33 +++++++++-
.../net/wireless/intel/iwlwifi/fw/api/scan.h | 4 +-
drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 9 ++-
.../wireless/intel/iwlwifi/fw/regulatory.c | 2 +-
drivers/net/wireless/intel/iwlwifi/fw/smem.c | 28 ++++++--
.../net/wireless/intel/iwlwifi/iwl-config.h | 2 +
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 64 ++++++++++++-------
drivers/net/wireless/intel/iwlwifi/mld/tx.c | 4 ++
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 31 ++++++---
.../intel/iwlwifi/mvm/ftm-initiator.c | 55 +++++++++++-----
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 10 +++
drivers/net/wireless/intel/iwlwifi/mvm/ptp.c | 4 +-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 45 ++++++++++++-
.../wireless/intel/iwlwifi/pcie/ctxt-info.c | 7 +-
15 files changed, 236 insertions(+), 63 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH v2] wifi: mwifiex: validate HT/VHT capability and operation IE lengths
From: Doruk Tan Ozturk @ 2026-07-15 18:55 UTC (permalink / raw)
To: briannorris; +Cc: francesco, kees, linux-wireless, linux-kernel, stable
In-Reply-To: <20260709100800.7026-1-doruk@0sec.ai>
mwifiex_update_bss_desc_with_ie() records raw pointers to the HT
Capabilities, HT Operation, VHT Capabilities, VHT Operation, 20/40 BSS
Coexistence and Operating Mode Notification elements taken straight out
of a beacon/probe-response buffer, without checking that each element is
long enough for the fixed-size structure that later consumers read. The
buffer is a tight kmemdup() of the on-air IEs (beacon_buf_size ==
ies->len), so a truncated element placed last leaves the stored pointer
one past the end of the allocation.
At association time these pointers are dereferenced at fixed offsets
regardless of the on-air length: mwifiex_cmd_append_11n_tlv() memcpy()s
sizeof(struct ieee80211_ht_cap) (26 bytes) from bcn_ht_cap and reads
bcn_ht_oper->ht_param, and mwifiex_cmd_append_11ac_tlv() memcpy()s
sizeof(struct ieee80211_vht_cap) (12 bytes) from bcn_vht_cap and reads
bcn_vht_oper->chan_width. A nearby AP (rogue / evil-twin; an open SSID
needs no credentials) advertising a BSS with a truncated HT/VHT cap
element therefore triggers a slab out-of-bounds read on the victim's
association attempt. This out-of-bounds read is the primary issue.
For the HT-Cap copy the over-read bytes are additionally placed into the
outgoing association request, so a limited amount of adjacent heap memory
can leak over the air. In station mode this is small (single-digit
bytes), because mwifiex_fill_cap_info() rewrites most of the copied
HT-Cap before transmission; the leak is a secondary effect.
mwifiex_set_sta_ht_cap() has the same missing-length pattern: in uAP mode
it reads two bytes of ieee80211_ht_cap.cap_info from a
cfg80211_find_ie(WLAN_EID_HT_CAPABILITY) result in a client association
request without checking the element length, a 1-2 byte out-of-bounds
read (used only to select an A-MSDU size, not leaked).
Reject the frame with -EINVAL when any of these elements is shorter than
the structure the driver later reads, matching the length validation the
FH/DS/CF/IBSS parameter-set cases in the same beacon parser already
perform. mwifiex_set_sta_ht_cap() returns void, so there the too-short
element is skipped instead.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
Changes in v2 (per Francesco Dolcini review):
- return -EINVAL on a too-short element instead of break, matching the
FH/DS/CF/IBSS and VENDOR_SPECIFIC cases in the same function.
mwifiex_set_sta_ht_cap() returns void, so there it stays a skip.
- switch the Assisted-by trailer to 0sec:multi-model.
drivers/net/wireless/marvell/mwifiex/scan.c | 12 ++++++++++++
drivers/net/wireless/marvell/mwifiex/util.c | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 97c0ec3b822e..22031faba057 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -1384,6 +1384,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->beacon_buf);
break;
case WLAN_EID_HT_CAPABILITY:
+ if (element_len < sizeof(struct ieee80211_ht_cap))
+ return -EINVAL;
bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
(current_ptr +
sizeof(struct ieee_types_header));
@@ -1392,6 +1394,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->beacon_buf);
break;
case WLAN_EID_HT_OPERATION:
+ if (element_len < sizeof(struct ieee80211_ht_operation))
+ return -EINVAL;
bss_entry->bcn_ht_oper =
(struct ieee80211_ht_operation *)(current_ptr +
sizeof(struct ieee_types_header));
@@ -1400,6 +1404,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->beacon_buf);
break;
case WLAN_EID_VHT_CAPABILITY:
+ if (element_len < sizeof(struct ieee80211_vht_cap))
+ return -EINVAL;
bss_entry->disable_11ac = false;
bss_entry->bcn_vht_cap =
(void *)(current_ptr +
@@ -1409,6 +1415,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->beacon_buf);
break;
case WLAN_EID_VHT_OPERATION:
+ if (element_len < sizeof(struct ieee80211_vht_operation))
+ return -EINVAL;
bss_entry->bcn_vht_oper =
(void *)(current_ptr +
sizeof(struct ieee_types_header));
@@ -1417,6 +1425,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
bss_entry->beacon_buf);
break;
case WLAN_EID_BSS_COEX_2040:
+ if (!element_len)
+ return -EINVAL;
bss_entry->bcn_bss_co_2040 = current_ptr;
bss_entry->bss_co_2040_offset =
(u16) (current_ptr - bss_entry->beacon_buf);
@@ -1427,6 +1437,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
(u16) (current_ptr - bss_entry->beacon_buf);
break;
case WLAN_EID_OPMODE_NOTIF:
+ if (!element_len)
+ return -EINVAL;
bss_entry->oper_mode = (void *)current_ptr;
bss_entry->oper_mode_offset =
(u16)((u8 *)bss_entry->oper_mode -
diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 7d3631d21223..844223c04e2e 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -721,7 +721,7 @@ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
ht_cap_ie = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies,
ies_len);
- if (ht_cap_ie) {
+ if (ht_cap_ie && ht_cap_ie->len >= sizeof(struct ieee80211_ht_cap)) {
ht_cap = (void *)(ht_cap_ie + 1);
node->is_11n_enabled = 1;
node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
--
2.43.0
^ permalink raw reply related
* [PATCH v2] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length
From: Doruk Tan Ozturk @ 2026-07-15 18:55 UTC (permalink / raw)
To: briannorris; +Cc: francesco, linux-wireless, linux-kernel, stable
In-Reply-To: <20260711071334.58307-1-doruk@0sec.ai>
mwifiex_search_oui_in_ie() reads the pairwise-cipher (PTK) count from a
beacon/probe-response RSN or WPA information element:
count = iebody->ptk_cnt[0];
and then walks "count" 4-byte OUIs from the element, comparing each with
memcmp(). The count byte comes straight from the (attacker-supplied) IE
and is never checked against the element's own length. The callers admit
the element on element_id alone (has_ieee_hdr() / has_vendor_hdr(), no
length check), so a crafted RSN/WPA IE with a large pairwise count makes
the walk read up to 255 * 4 bytes past the element -- an out-of-bounds
read of the kmemdup()'d beacon buffer, reachable from any AP whose
beacon/probe response is processed during scan result parsing.
Pass the number of available IE bytes to the walk and reject a count
whose OUI list would not fit, keeping the loop within the element.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
Changes in v2 (per Francesco Dolcini's review):
- store offsetof(struct ie_body, ptk_body) in a named variable
(ptk_body_offset) and reuse it in both bounds checks; no
functional change.
- switch the Assisted-by trailer to 0sec:multi-model.
drivers/net/wireless/marvell/mwifiex/scan.c | 22 ++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 97c0ec3b822e..33ef8af0a5e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -104,12 +104,21 @@ has_vendor_hdr(struct ieee_types_vendor_specific *ie, u8 key)
* a given oui in PTK.
*/
static u8
-mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
+mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui, int ie_len)
{
+ const size_t ptk_body_offset = offsetof(struct ie_body, ptk_body);
u8 count;
+ /* Need grp_key_oui[4] + ptk_cnt[2] before reading the OUI count. */
+ if (ie_len < (int)ptk_body_offset)
+ return MWIFIEX_OUI_NOT_PRESENT;
+
count = iebody->ptk_cnt[0];
+ /* Reject an OUI count whose list would run past the element. */
+ if (ptk_body_offset + count * sizeof(iebody->ptk_body) > (size_t)ie_len)
+ return MWIFIEX_OUI_NOT_PRESENT;
+
/* There could be multiple OUIs for PTK hence
1) Take the length.
2) Check all the OUIs for AES.
@@ -143,11 +152,14 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
u8 ret = MWIFIEX_OUI_NOT_PRESENT;
if (has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
+ int ie_len = (int)bss_desc->bcn_rsn_ie->ieee_hdr.len -
+ RSN_GTK_OUI_OFFSET;
+
iebody = (struct ie_body *)
(((u8 *) bss_desc->bcn_rsn_ie->data) +
RSN_GTK_OUI_OFFSET);
oui = &mwifiex_rsn_oui[cipher][0];
- ret = mwifiex_search_oui_in_ie(iebody, oui);
+ ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
if (ret)
return ret;
}
@@ -169,10 +181,14 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
u8 ret = MWIFIEX_OUI_NOT_PRESENT;
if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) {
+ int ie_len = (int)bss_desc->bcn_wpa_ie->vend_hdr.len -
+ (int)sizeof(bss_desc->bcn_wpa_ie->vend_hdr.oui) -
+ WPA_GTK_OUI_OFFSET;
+
iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data +
WPA_GTK_OUI_OFFSET);
oui = &mwifiex_wpa_oui[cipher][0];
- ret = mwifiex_search_oui_in_ie(iebody, oui);
+ ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
if (ret)
return ret;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4] wifi: brcmfmac: add DPP support
From: Arend van Spriel @ 2026-07-15 18:46 UTC (permalink / raw)
To: HungTsung Huang
Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl, linux-kernel,
Johannes Berg
In-Reply-To: <20260715092229.GA667683@ISCN5CG5251XQT.infineon.com>
On 15/07/2026 11:22, HungTsung Huang wrote:
> Hi Arend,
>
> Thanks for the clarification.
>
> Could you please confirm whether it is OK to submit the standalone P2P fix
> to wireless in parallel to wireless-next origin/main? My understanding is
> that the P2P fix does not need to wait for the DPP support patch to be
> accepted, since it fixes pre-existing bugs and the DPP patch no longer
> depends on it.
Yes. You can submit the P2P fix in parallel. I am not sure if
wireless-next is rebased against wireless in a release cycle. Maybe this
kind of scenario is a reason to do so.
> The reason I added:
>>> + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif &&
>>> p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {
>
> was that DPP public action frames can be sent through the primary interface
> without a P2P device vif being created. The existing peer channel search path
> assumed the P2P device vif was always available before accessing saved
> Probe Request IEs, which could dereference a NULL vif in that case. However,
> I agree this is a pre-existing P2P bug rather than part of DPP support, so I
> moved it into the standalone P2P fix patch.
Thanks.
Regards,
Arend
^ permalink raw reply
* [PATCH wireless-next] wifi: mac80211: fix monitor min_def bandwidth
From: Miri Korenblit @ 2026-07-15 18:33 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Due to reshuffling, the min_def is no longer calculated
taking a newly created monitor interface into account as
link->conf->chanctx_conf is only assigned after the new
bandwidth has been calculated. To handle this, rsvd_for
is assigned, but the monitor code didn't handle that.
Fix this by checking rsvd_for for monitor explicitly.
Fixes: 3f451a2cf56c ("wifi: mac80211: use for_each_chanctx_user_* in one more place")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/chan.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 5152b84a3357..75bb204ad743 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -607,10 +607,12 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
max_bw = max(max_bw, width);
}
- if (!rsvd_for ||
- rsvd_for->sdata == rcu_access_pointer(local->monitor_sdata))
+ if (!rsvd_for)
goto check_monitor;
+ if (rsvd_for->sdata == rcu_access_pointer(local->monitor_sdata))
+ return max(max_bw, ctx->conf.def.width);
+
/* Consider the link for which this chanctx is reserved/going to be assigned */
width = ieee80211_get_width_of_link(rsvd_for);
max_bw = max(max_bw, width);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] wifi: mwifiex: validate HT/VHT capability and operation IE lengths
From: Doruk Tan Ozturk @ 2026-07-15 18:33 UTC (permalink / raw)
To: Francesco Dolcini
Cc: Brian Norris, Kees Cook, linux-wireless, linux-kernel, stable
In-Reply-To: <20260715163458.GA149147@francesco-nb>
> My advise would be to do the same we are already doing, and unless I am
> wrong, it means that we skip the whole frame if a corruption is detected.
Makes sense, I'll switch these to -EINVAL and send a v2. Thanks.
-Doruk
^ permalink raw reply
* [PATCH wireless-next 1/2] wifi: mac80211: ibss: read deauth reason_code after frame length check
From: Miri Korenblit @ 2026-07-15 18:27 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shahar Tzarfati
From: Shahar Tzarfati <shahar.tzarfati@intel.com>
The function was reading reason_code from the frame before validating
that the frame is at least IEEE80211_DEAUTH_FRAME_LEN bytes long.
Move the reason_code read to after the length check so the field is
guaranteed to be present before it is accessed.
Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/ibss.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index d0fd6054f182..9915dd5c36df 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -881,11 +881,13 @@ static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
size_t len)
{
- u16 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
+ u16 reason;
if (len < IEEE80211_DEAUTH_FRAME_LEN)
return;
+ reason = le16_to_cpu(mgmt->u.deauth.reason_code);
+
ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
ibss_dbg(sdata, "\tBSSID=%pM (reason: %d)\n", mgmt->bssid, reason);
sta_info_destroy_addr(sdata, mgmt->sa);
--
2.34.1
^ permalink raw reply related
* [PATCH wireless-next 2/2] wifi: mac80211: mlme: read deauth reason_code after frame length check
From: Miri Korenblit @ 2026-07-15 18:27 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shahar Tzarfati
In-Reply-To: <20260715212706.db26604650bd.I2caa73c396b8c9d357224b9334d5df3cafac498e@changeid>
From: Shahar Tzarfati <shahar.tzarfati@intel.com>
The function was reading reason_code from the frame before validating
that the frame is at least IEEE80211_DEAUTH_FRAME_LEN bytes long.
Move the reason_code read to after the length check so the field is
guaranteed to be present before it is accessed. Also replace the
open-coded 24 + 2 with the named constant IEEE80211_DEAUTH_FRAME_LEN
for clarity.
Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
net/mac80211/mlme.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9e92337bb6f9..f180fcd477d0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5641,13 +5641,15 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
+ u16 reason_code;
lockdep_assert_wiphy(sdata->local->hw.wiphy);
- if (len < 24 + 2)
+ if (len < IEEE80211_DEAUTH_FRAME_LEN)
return;
+ reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
+
if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) {
ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code);
return;
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox