Skip to content

Commit 682b6dc

Browse files
committed
wifi: iwlwifi: mvm: don't trust firmware n_channels
If the firmware sends us a corrupted MCC response with n_channels much larger than the command response can be, we might copy far too much (uninitialized) memory and even crash if the n_channels is large enough to make it run out of the one page allocated for the FW response. Fix that by checking the lengths. Doing a < comparison would be sufficient, but the firmware should be doing it correctly, so check more strictly. Fixes: dcaf9f5 ("iwlwifi: mvm: add MCC update FW API") Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: Gregory Greenman <[email protected]> Link: https://lore.kernel.org/r/20230514120631.d7b233139eb4.I51fd319df8e9d41881fc8450e83d78049518a79a@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent d0246a0 commit 682b6dc

File tree

1 file changed

+10
-0
lines changed
  • drivers/net/wireless/intel/iwlwifi/mvm

1 file changed

+10
-0
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/nvm.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
445445
struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data;
446446

447447
n_channels = __le32_to_cpu(mcc_resp->n_channels);
448+
if (iwl_rx_packet_payload_len(pkt) !=
449+
struct_size(mcc_resp, channels, n_channels)) {
450+
resp_cp = ERR_PTR(-EINVAL);
451+
goto exit;
452+
}
448453
resp_len = sizeof(struct iwl_mcc_update_resp) +
449454
n_channels * sizeof(__le32);
450455
resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
@@ -456,6 +461,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
456461
struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;
457462

458463
n_channels = __le32_to_cpu(mcc_resp_v3->n_channels);
464+
if (iwl_rx_packet_payload_len(pkt) !=
465+
struct_size(mcc_resp_v3, channels, n_channels)) {
466+
resp_cp = ERR_PTR(-EINVAL);
467+
goto exit;
468+
}
459469
resp_len = sizeof(struct iwl_mcc_update_resp) +
460470
n_channels * sizeof(__le32);
461471
resp_cp = kzalloc(resp_len, GFP_KERNEL);

0 commit comments

Comments
 (0)