summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2026-07-14 14:19:57 +0300
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>2026-07-14 20:45:20 +0300
commit77f33bed0cb49a11f03427f2fa368830c1cae3c2 (patch)
tree44b83ec31f379d50454c3243ed41591efafaa8b4
parentb77c6f50b1f80414cb3f542ae72e532ed90fc7f7 (diff)
wifi: iwlwifi: mvm: validate MCC header before n_channels
MCC response parsing read n_channels from v8/v4/v3 response variants before ensuring the payload contained the fixed response header. Add a minimum payload-length check for each response version before reading n_channels, and keep the existing exact-size validation for the channels array payload. Assisted-by: GitHub Copilot:gpt-5.3-codex Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Link: https://patch.msgid.link/20260714141909.cb2cef3d3e7e.Iee7b48614289da576de842157ad3730b7589a4b1@changeid Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/nvm.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index 953218f1e025..f76e57399c1f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2019, 2021-2025 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2019, 2021-2026 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -416,6 +416,7 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
int ret, resp_ver;
u32 status;
int resp_len, n_channels;
+ unsigned int pkt_len;
u16 mcc;
if (WARN_ON_ONCE(!iwl_mvm_is_lar_supported(mvm)))
@@ -431,6 +432,7 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
return ERR_PTR(ret);
pkt = cmd.resp_pkt;
+ pkt_len = iwl_rx_packet_payload_len(pkt);
resp_ver = iwl_fw_lookup_notif_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
MCC_UPDATE_CMD, 0);
@@ -439,9 +441,18 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
if (resp_ver >= 8) {
struct iwl_mcc_update_resp_v8 *mcc_resp_v8 = (void *)pkt->data;
+ if (IWL_FW_CHECK(mvm, pkt_len < sizeof(*mcc_resp_v8),
+ "MCC v8 response too short: %u\n", pkt_len)) {
+ resp_cp = ERR_PTR(-EINVAL);
+ goto exit;
+ }
+
n_channels = __le32_to_cpu(mcc_resp_v8->n_channels);
- if (iwl_rx_packet_payload_len(pkt) !=
- struct_size(mcc_resp_v8, channels, n_channels)) {
+ if (IWL_FW_CHECK(mvm,
+ pkt_len !=
+ struct_size(mcc_resp_v8, channels, n_channels),
+ "invalid MCC v8 response size: %u (n_channels=%d)\n",
+ pkt_len, n_channels)) {
resp_cp = ERR_PTR(-EINVAL);
goto exit;
}
@@ -464,9 +475,18 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT)) {
struct iwl_mcc_update_resp_v4 *mcc_resp_v4 = (void *)pkt->data;
+ if (IWL_FW_CHECK(mvm, pkt_len < sizeof(*mcc_resp_v4),
+ "MCC v4 response too short: %u\n", pkt_len)) {
+ resp_cp = ERR_PTR(-EINVAL);
+ goto exit;
+ }
+
n_channels = __le32_to_cpu(mcc_resp_v4->n_channels);
- if (iwl_rx_packet_payload_len(pkt) !=
- struct_size(mcc_resp_v4, channels, n_channels)) {
+ if (IWL_FW_CHECK(mvm,
+ pkt_len !=
+ struct_size(mcc_resp_v4, channels, n_channels),
+ "invalid MCC v4 response size: %u (n_channels=%d)\n",
+ pkt_len, n_channels)) {
resp_cp = ERR_PTR(-EINVAL);
goto exit;
}
@@ -489,9 +509,18 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
} else {
struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;
+ if (IWL_FW_CHECK(mvm, pkt_len < sizeof(*mcc_resp_v3),
+ "MCC v3 response too short: %u\n", pkt_len)) {
+ resp_cp = ERR_PTR(-EINVAL);
+ goto exit;
+ }
+
n_channels = __le32_to_cpu(mcc_resp_v3->n_channels);
- if (iwl_rx_packet_payload_len(pkt) !=
- struct_size(mcc_resp_v3, channels, n_channels)) {
+ if (IWL_FW_CHECK(mvm,
+ pkt_len !=
+ struct_size(mcc_resp_v3, channels, n_channels),
+ "invalid MCC v3 response size: %u (n_channels=%d)\n",
+ pkt_len, n_channels)) {
resp_cp = ERR_PTR(-EINVAL);
goto exit;
}