diff options
author | Johannes Berg <johannes.berg@intel.com> | 2020-12-09 23:16:24 +0200 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2020-12-10 00:14:14 +0200 |
commit | efc0ec5afb6e1488b3bdc4bbf85533d79d7e5f9f (patch) | |
tree | 5c9ab5906333368c61f7cf9bf6efd5136e76f135 /drivers/net/wireless/intel/iwlwifi/mvm/rx.c | |
parent | c6bae216907119a39e204a5011bd22e6c816cedb (diff) | |
download | linux-efc0ec5afb6e1488b3bdc4bbf85533d79d7e5f9f.tar.gz linux-efc0ec5afb6e1488b3bdc4bbf85533d79d7e5f9f.tar.bz2 linux-efc0ec5afb6e1488b3bdc4bbf85533d79d7e5f9f.zip |
iwlwifi: validate MPDU length against notification length
The MPDU contained in a notification shouldn't be larger than the
notification size itself is, validate this.
Reported-by: Haggai Abramovsky <haggai.abramovsky@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20201209231352.7c721ad37014.Id5746874ecfa208b60baa62691b2d9dc5dd4d89c@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rx.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 2ffe92d79148..af3151553569 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -349,7 +349,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, struct iwl_rx_mpdu_res_start *rx_res; struct ieee80211_sta *sta = NULL; struct sk_buff *skb; - u32 len; + u32 len, pkt_len = iwl_rx_packet_payload_len(pkt); u32 rate_n_flags; u32 rx_pkt_status; u8 crypt_len = 0; @@ -358,6 +358,12 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res)); len = le16_to_cpu(rx_res->byte_count); + + if (unlikely(len + sizeof(*rx_res) + sizeof(__le32) > pkt_len)) { + IWL_DEBUG_DROP(mvm, "FW lied about packet len\n"); + return; + } + rx_pkt_status = get_unaligned_le32((__le32 *) (pkt->data + sizeof(*rx_res) + len)); |