]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds
authorMasashi Honma <masashi.honma@gmail.com>
Tue, 25 Sep 2018 02:15:01 +0000 (11:15 +0900)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 24 Apr 2019 08:09:09 +0000 (10:09 +0200)
Use array_index_nospec() to sanitize i with respect to speculation.

Note that the user doesn't control i directly, but can make it out
of bounds by not finding a threshold in the array.

Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
[add note about user control, as explained by Masashi]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
CVE-2017-5753

(cherry picked from commit 1222a16014888ed9733c11e221730d4a8196222b)
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
net/wireless/nl80211.c

index 66509123c3a69d72b094b44fbe93d433c6161a19..dd7d1af360ba58dc6e1f85947829f70d699492d4 100644 (file)
@@ -9798,7 +9798,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        s32 last, low, high;
        u32 hyst;
-       int i, n;
+       int i, n, low_index;
        int err;
 
        /* RSSI reporting disabled? */
@@ -9835,10 +9835,19 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
                if (last < wdev->cqm_config->rssi_thresholds[i])
                        break;
 
-       low = i > 0 ?
-               (wdev->cqm_config->rssi_thresholds[i - 1] - hyst) : S32_MIN;
-       high = i < n ?
-               (wdev->cqm_config->rssi_thresholds[i] + hyst - 1) : S32_MAX;
+       low_index = i - 1;
+       if (low_index >= 0) {
+               low_index = array_index_nospec(low_index, n);
+               low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
+       } else {
+               low = S32_MIN;
+       }
+       if (i < n) {
+               i = array_index_nospec(i, n);
+               high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
+       } else {
+               high = S32_MAX;
+       }
 
        return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
 }