iwlwifi: mvm: avoid possible access out of array.
authorMordechay Goodstein <mordechay.goodstein@intel.com>
Sun, 21 Oct 2018 15:27:26 +0000 (18:27 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2020 13:46:14 +0000 (14:46 +0100)
[ Upstream commit b0d795a9ae558209656b18930c2b4def5f8fdfb8 ]

The value in txq_id can be out of array scope,
validate it before accessing the array.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Fixes: cf961e16620f ("iwlwifi: mvm: support dqa-mode agg on non-shared queue")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wireless/intel/iwlwifi/mvm/sta.c

index 0cfdbaa2af3a774df050953e01cbc31f90b51f3d..684c0f65a0528a6bcb46b17276a8b0a64892ff46 100644 (file)
@@ -2417,7 +2417,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_mvm_tid_data *tid_data;
        u16 normalized_ssn;
-       int txq_id;
+       u16 txq_id;
        int ret;
 
        if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
@@ -2452,17 +2452,24 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
         */
        txq_id = mvmsta->tid_data[tid].txq_id;
        if (txq_id == IWL_MVM_INVALID_QUEUE) {
-               txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
-                                                IWL_MVM_DQA_MIN_DATA_QUEUE,
-                                                IWL_MVM_DQA_MAX_DATA_QUEUE);
-               if (txq_id < 0) {
-                       ret = txq_id;
+               ret = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
+                                             IWL_MVM_DQA_MIN_DATA_QUEUE,
+                                             IWL_MVM_DQA_MAX_DATA_QUEUE);
+               if (ret < 0) {
                        IWL_ERR(mvm, "Failed to allocate agg queue\n");
                        goto release_locks;
                }
 
+               txq_id = ret;
+
                /* TXQ hasn't yet been enabled, so mark it only as reserved */
                mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
+       } else if (WARN_ON(txq_id >= IWL_MAX_HW_QUEUES)) {
+               ret = -ENXIO;
+               IWL_ERR(mvm, "tid_id %d out of range (0, %d)!\n",
+                       tid, IWL_MAX_HW_QUEUES - 1);
+               goto out;
+
        } else if (unlikely(mvm->queue_info[txq_id].status ==
                            IWL_MVM_QUEUE_SHARED)) {
                ret = -ENXIO;