wifi: mac80211: validate assoc response channel config
authorJohannes Berg <johannes.berg@intel.com>
Mon, 29 Jan 2024 18:34:43 +0000 (19:34 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 8 Feb 2024 12:07:37 +0000 (13:07 +0100)
Due to the earlier restructuring we now mostly ignore
the channel configuration in the association response,
apart from the HT/VHT checks we had.

Don't do that, but parse it and update, also dropping the
association if the AP changed its mode in the response.

Link: https://msgid.link/20240129194108.b3efa5eae60c.I1b70c9fd56781b22cdfdca55d34d69f7d0733e31@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/mlme.c

index 31d6a56..da20210 100644 (file)
@@ -867,7 +867,7 @@ free:
 
 static int ieee80211_config_bw(struct ieee80211_link_data *link,
                               struct ieee802_11_elems *elems,
-                              u64 *changed)
+                              bool update, u64 *changed)
 {
        struct ieee80211_channel *channel = link->conf->chanreq.oper.chan;
        struct ieee80211_sub_if_data *sdata = link->sdata;
@@ -942,6 +942,11 @@ static int ieee80211_config_bw(struct ieee80211_link_data *link,
                return -EINVAL;
        }
 
+       if (!update) {
+               link->conf->chanreq = chanreq;
+               return 0;
+       }
+
        /*
         * We're tracking the current AP here, so don't do any further checks
         * here. This keeps us from playing ping-pong with regulatory, without
@@ -4505,6 +4510,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
        /*
         * We previously checked these in the beacon/probe response, so
         * they should be present here. This is just a safety net.
+        * Note that the ieee80211_config_bw() below would also check
+        * for this (and more), but this has better error reporting.
         */
        if (!is_6ghz && link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_HT &&
            (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
@@ -4522,6 +4529,14 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
                goto out;
        }
 
+       /* check/update if AP changed anything in assoc response vs. scan */
+       if (ieee80211_config_bw(link, elems,
+                               link_id == assoc_data->assoc_link_id,
+                               changed)) {
+               ret = false;
+               goto out;
+       }
+
        if (WARN_ON(!link->conf->chanreq.oper.chan)) {
                ret = false;
                goto out;
@@ -6595,7 +6610,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
 
        changed |= ieee80211_recalc_twt_req(sdata, sband, link, link_sta, elems);
 
-       if (ieee80211_config_bw(link, elems, &changed)) {
+       if (ieee80211_config_bw(link, elems, true, &changed)) {
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       WLAN_REASON_DEAUTH_LEAVING,
                                       true, deauth_buf);