Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e519a404 authored by Johannes Berg's avatar Johannes Berg Committed by Greg Kroah-Hartman
Browse files

wifi: iwlwifi: mvm: don't trust firmware n_channels



[ Upstream commit 682b6dc29d98e857e6ca4bbc077c7dc2899b7473 ]

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: dcaf9f5e ("iwlwifi: mvm: add MCC update FW API")
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230514120631.d7b233139eb4.I51fd319df8e9d41881fc8450e83d78049518a79a@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent d0baaadd
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -508,6 +508,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
		struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data;

		n_channels =  __le32_to_cpu(mcc_resp->n_channels);
		if (iwl_rx_packet_payload_len(pkt) !=
		    struct_size(mcc_resp, channels, n_channels)) {
			resp_cp = ERR_PTR(-EINVAL);
			goto exit;
		}
		resp_len = sizeof(struct iwl_mcc_update_resp) +
			   n_channels * sizeof(__le32);
		resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
@@ -519,6 +524,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
		struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data;

		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)) {
			resp_cp = ERR_PTR(-EINVAL);
			goto exit;
		}
		resp_len = sizeof(struct iwl_mcc_update_resp) +
			   n_channels * sizeof(__le32);
		resp_cp = kzalloc(resp_len, GFP_KERNEL);