]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
iwlwifi: mvm: add size checks for range response notification
authorAvraham Stern <avraham.stern@intel.com>
Wed, 9 Dec 2020 21:16:48 +0000 (23:16 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Wed, 9 Dec 2020 22:16:06 +0000 (00:16 +0200)
The range response notification has several versions. Check the
notification size according to the expected notification version.
Notifications with incorrect size will be ignored.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20201209231352.ee57c3214d05.I810d7de33fb08001ef1a2e24714d5b68932e088e@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c

index d121f682f8759df834c907584b42ca40012c823d..a4fd0bf9ba19622d25f9cf81b3a2ffb18bebb85e 100644 (file)
@@ -977,9 +977,44 @@ iwl_mvm_ftm_pasn_update_pn(struct iwl_mvm *mvm,
        }
 }
 
+static u8 iwl_mvm_ftm_get_range_resp_ver(struct iwl_mvm *mvm)
+{
+       if (!fw_has_api(&mvm->fw->ucode_capa,
+                       IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ))
+               return 5;
+
+       /* Starting from version 8, the FW advertises the version */
+       if (mvm->cmd_ver.range_resp >= 8)
+               return mvm->cmd_ver.range_resp;
+       else if (fw_has_api(&mvm->fw->ucode_capa,
+                           IWL_UCODE_TLV_API_FTM_RTT_ACCURACY))
+               return 7;
+
+       /* The first version of the new range request API */
+       return 6;
+}
+
+static bool iwl_mvm_ftm_resp_size_validation(u8 ver, unsigned int pkt_len)
+{
+       switch (ver) {
+       case 8:
+               return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v8);
+       case 7:
+               return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v7);
+       case 6:
+               return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v6);
+       case 5:
+               return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v5);
+       default:
+               WARN_ONCE(1, "FTM: unsupported range response version %u", ver);
+               return false;
+       }
+}
+
 void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       unsigned int pkt_len = iwl_rx_packet_payload_len(pkt);
        struct iwl_tof_range_rsp_ntfy_v5 *fw_resp_v5 = (void *)pkt->data;
        struct iwl_tof_range_rsp_ntfy_v6 *fw_resp_v6 = (void *)pkt->data;
        struct iwl_tof_range_rsp_ntfy_v7 *fw_resp_v7 = (void *)pkt->data;
@@ -988,6 +1023,7 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
        bool new_api = fw_has_api(&mvm->fw->ucode_capa,
                                  IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ);
        u8 num_of_aps, last_in_batch;
+       u8 notif_ver = iwl_mvm_ftm_get_range_resp_ver(mvm);
 
        lockdep_assert_held(&mvm->mutex);
 
@@ -995,6 +1031,9 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
                return;
        }
 
+       if (unlikely(!iwl_mvm_ftm_resp_size_validation(notif_ver, pkt_len)))
+               return;
+
        if (new_api) {
                if (iwl_mvm_ftm_range_resp_valid(mvm, fw_resp_v8->request_id,
                                                 fw_resp_v8->num_of_aps))
@@ -1021,11 +1060,10 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
                int peer_idx;
 
                if (new_api) {
-                       if (mvm->cmd_ver.range_resp == 8) {
+                       if (notif_ver == 8) {
                                fw_ap = &fw_resp_v8->ap[i];
                                iwl_mvm_ftm_pasn_update_pn(mvm, fw_ap);
-                       } else if (fw_has_api(&mvm->fw->ucode_capa,
-                                             IWL_UCODE_TLV_API_FTM_RTT_ACCURACY)) {
+                       } else if (notif_ver == 7) {
                                fw_ap = (void *)&fw_resp_v7->ap[i];
                        } else {
                                fw_ap = (void *)&fw_resp_v6->ap[i];