4.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Luca Coelho <luciano.coe...@intel.com>

commit 3d71c3f1f50cf309bd20659422af549bc784bfff upstream.

The rs_rate_from_ucode_rate() function may return -EINVAL if the rate
is invalid, but none of the callsites check for the error, potentially
making us access arrays with index IWL_RATE_INVALID, which is larger
than the arrays, causing an out-of-bounds access.  This will trigger
KASAN warnings, such as the one reported in the bugzilla issue
mentioned below.

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=200659

Cc: sta...@vger.kernel.org
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Signed-off-by: Kalle Valo <kv...@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/net/wireless/intel/iwlwifi/mvm/rs.c |   24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1218,7 +1218,11 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm
            !(info->flags & IEEE80211_TX_STAT_AMPDU))
                return;
 
-       rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
+       if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
+                                   &tx_resp_rate)) {
+               WARN_ON_ONCE(1);
+               return;
+       }
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        /* Disable last tx check if we are debugging with fixed rate but
@@ -1269,7 +1273,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm
         */
        table = &lq_sta->lq;
        lq_hwrate = le32_to_cpu(table->rs_table[0]);
-       rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
+       if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
+               WARN_ON_ONCE(1);
+               return;
+       }
 
        /* Here we actually compare this rate to the latest LQ command */
        if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
@@ -1371,8 +1378,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm
                /* Collect data for each rate used during failed TX attempts */
                for (i = 0; i <= retries; ++i) {
                        lq_hwrate = le32_to_cpu(table->rs_table[i]);
-                       rs_rate_from_ucode_rate(lq_hwrate, info->band,
-                                               &lq_rate);
+                       if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
+                                                   &lq_rate)) {
+                               WARN_ON_ONCE(1);
+                               return;
+                       }
+
                        /*
                         * Only collect stats if retried rate is in the same RS
                         * table as active/search.
@@ -3241,7 +3252,10 @@ static void rs_build_rates_table_from_fi
        for (i = 0; i < num_rates; i++)
                lq_cmd->rs_table[i] = ucode_rate_le32;
 
-       rs_rate_from_ucode_rate(ucode_rate, band, &rate);
+       if (rs_rate_from_ucode_rate(ucode_rate, band, &rate)) {
+               WARN_ON_ONCE(1);
+               return;
+       }
 
        if (is_mimo(&rate))
                lq_cmd->mimo_delim = num_rates - 1;


Reply via email to