wifi: iwlwifi: mvm: fix access to fw_id_to_mac_id
authorGregory Greenman <gregory.greenman@intel.com>
Sun, 14 May 2023 09:15:49 +0000 (12:15 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 16 May 2023 17:27:04 +0000 (10:27 -0700)
RCU protected fw_id_to_mac_id can be initialized with either
an error code or NULL. Thus, after dereferencing need to check
the value with IS_ERR_OR_NULL() and not only that it is not NULL.
Fix it.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230514120631.ec5f2880e81c.Ifa8c0f451df2835bde800f5c3670cc46238a3bd8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c

index 3963a0d4ed0427ba004e0bb5f846df5ab4eb8332..652a603c4500efed3be6162d4f26a520eeda3f93 100644 (file)
@@ -526,6 +526,11 @@ iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                rcu_read_lock();
 
                sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id]);
+               if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
+                       rcu_read_unlock();
+                       return PTR_ERR_OR_ZERO(sta);
+               }
+
                if (sta->mfp && (peer->ftm.trigger_based || peer->ftm.non_trigger_based))
                        FTM_PUT_FLAG(PMF);
 
index 01432274a6da976462cdff82b3bd6a6ae6506974..6226e4e54a51d2775a19174f7683d2c1db5ec729 100644 (file)
@@ -691,6 +691,11 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t)
 
                rcu_read_lock();
                sta = rcu_dereference(buf->mvm->fw_id_to_mac_id[sta_id]);
+               if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
+                       rcu_read_unlock();
+                       goto out;
+               }
+
                mvmsta = iwl_mvm_sta_from_mac80211(sta);
 
                /* SN is set to the last expired frame + 1 */
@@ -712,6 +717,8 @@ void iwl_mvm_reorder_timer_expired(struct timer_list *t)
                          entries[index].e.reorder_time +
                          1 + RX_REORDER_BUF_TIMEOUT_MQ);
        }
+
+out:
        spin_unlock(&buf->lock);
 }
 
index 1e8592d3bcd6ac4a2796c720ef1ec795a123a27b..05a54a69c1357c59f121803204c8d7d448d4c0ef 100644 (file)
@@ -281,7 +281,7 @@ static void iwl_mvm_rx_agg_session_expired(struct timer_list *t)
         * A-MDPU and hence the timer continues to run. Then, the
         * timer expires and sta is NULL.
         */
-       if (!sta)
+       if (IS_ERR_OR_NULL(sta))
                goto unlock;
 
        mvm_sta = iwl_mvm_sta_from_mac80211(sta);
@@ -3782,6 +3782,9 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
                u8 sta_id = mvmvif->deflink.ap_sta_id;
                sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
                                                lockdep_is_held(&mvm->mutex));
+               if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta)))
+                       return NULL;
+
                return sta->addr;
        }
 
@@ -3819,6 +3822,11 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
 
        if (keyconf->cipher == WLAN_CIPHER_SUITE_TKIP) {
                addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
+               if (!addr) {
+                       IWL_ERR(mvm, "Failed to find mac address\n");
+                       return -EINVAL;
+               }
+
                /* get phase 1 key from mac80211 */
                ieee80211_get_key_rx_seq(keyconf, 0, &seq);
                ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
index 10d7178f10718ebe350494c40235368eacfeeb6c..00719e1304386454f350677322764e46483fab57 100644 (file)
@@ -1875,7 +1875,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
        mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, sta_id);
 
        sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
-       if (WARN_ON_ONCE(!sta || !sta->wme)) {
+       if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta) || !sta->wme)) {
                rcu_read_unlock();
                return;
        }