wifi: iwlwifi: mvm: don't access packet before checking len
authorMordechay Goodstein <mordechay.goodstein@intel.com>
Mon, 5 Dec 2022 08:35:40 +0000 (10:35 +0200)
committerGregory Greenman <gregory.greenman@intel.com>
Wed, 7 Dec 2022 15:35:58 +0000 (17:35 +0200)
Currently in sniffer mode we access pkt fields before checking that
the frame has the length to access it. Fix this by moving the check
to before the access.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20221205102808.934da230c698.Ib56f11bbc8978e15d38394336a929cb4996ba39e@changeid
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index 5f782ca1e254150cc9c452185404c6985bcee862..97b67270f3847b1c66343559f4a83234f8ff7d1f 100644 (file)
@@ -2066,22 +2066,30 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
        struct ieee80211_rx_status *rx_status;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_rx_no_data *desc = (void *)pkt->data;
-       u32 rssi = le32_to_cpu(desc->rssi);
-       u32 info_type = le32_to_cpu(desc->info) & RX_NO_DATA_INFO_TYPE_MSK;
+       u32 rssi;
+       u32 info_type;
        struct ieee80211_sta *sta = NULL;
        struct sk_buff *skb;
-       struct iwl_mvm_rx_phy_data phy_data = {
-               .d0 = desc->phy_info[0],
-               .d1 = desc->phy_info[1],
-               .phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD,
-               .gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time),
-               .rate_n_flags = le32_to_cpu(desc->rate),
-               .energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK),
-               .energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK),
-               .channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK),
-       };
+       struct iwl_mvm_rx_phy_data phy_data;
        u32 format;
 
+       if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
+               return;
+
+       if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(struct iwl_rx_no_data)))
+               return;
+
+       rssi = le32_to_cpu(desc->rssi);
+       info_type = le32_to_cpu(desc->info) & RX_NO_DATA_INFO_TYPE_MSK;
+       phy_data.d0 = desc->phy_info[0];
+       phy_data.d1 = desc->phy_info[1];
+       phy_data.phy_info = IWL_RX_MPDU_PHY_TSF_OVERLOAD;
+       phy_data.gp2_on_air_rise = le32_to_cpu(desc->on_air_rise_time);
+       phy_data.rate_n_flags = le32_to_cpu(desc->rate);
+       phy_data.energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK);
+       phy_data.energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK);
+       phy_data.channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK);
+
        if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP,
                                    RX_NO_DATA_NOTIF, 0) < 2) {
                IWL_DEBUG_DROP(mvm, "Got an old rate format. Old rate: 0x%x\n",
@@ -2093,12 +2101,6 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
 
        format = phy_data.rate_n_flags & RATE_MCS_MOD_TYPE_MSK;
 
-       if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(*desc)))
-               return;
-
-       if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
-               return;
-
        /* Dont use dev_alloc_skb(), we'll have enough headroom once
         * ieee80211_hdr pulled.
         */