Search Linux Wireless

[PATCH wireless 06/12] wifi: iwlwifi: mvm: fix access to fw_id_to_mac_id

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Gregory Greenman <gregory.greenman@xxxxxxxxx>

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@xxxxxxxxx>
---
 drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c |  5 +++++
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c          |  7 +++++++
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c           | 10 +++++++++-
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c            |  2 +-
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
index 3963a0d4ed04..652a603c4500 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
@@ -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);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 01432274a6da..6226e4e54a51 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -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);
 }
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 1e8592d3bcd6..05a54a69c135 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -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);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 10d7178f1071..00719e130438 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -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;
 	}
-- 
2.38.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux