]> www.infradead.org Git - users/hch/configfs.git/commitdiff
wifi: mac80211: check SSID in beacon
authorJohannes Berg <johannes.berg@intel.com>
Wed, 12 Jun 2024 12:38:10 +0000 (14:38 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 26 Jun 2024 08:22:10 +0000 (10:22 +0200)
Check that the SSID in beacons is correct, if it's not hidden
and beacon protection is enabled (otherwise there's no value).
If it doesn't match, disconnect.

Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20240612143809.8b24a3d26a3d.I3e3ef31dbd2ec606be74d502a9d00dd9514c6885@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/mlme.c

index e76b887a46eb57896fa0b8aeba358560a41e0afe..3d207d79d11f70d8ee11b5d9706a776e1d057b1d 100644 (file)
@@ -6667,6 +6667,29 @@ handle:
        }
 }
 
+static bool ieee80211_mgd_ssid_mismatch(struct ieee80211_sub_if_data *sdata,
+                                       const struct ieee802_11_elems *elems)
+{
+       struct ieee80211_vif_cfg *cfg = &sdata->vif.cfg;
+       static u8 zero_ssid[IEEE80211_MAX_SSID_LEN];
+
+       if (!elems->ssid)
+               return false;
+
+       /* hidden SSID: zero length */
+       if (elems->ssid_len == 0)
+               return false;
+
+       if (elems->ssid_len != cfg->ssid_len)
+               return true;
+
+       /* hidden SSID: zeroed out */
+       if (memcmp(elems->ssid, zero_ssid, elems->ssid_len))
+               return false;
+
+       return memcmp(elems->ssid, cfg->ssid, cfg->ssid_len);
+}
+
 static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
                                     struct ieee80211_hdr *hdr, size_t len,
                                     struct ieee80211_rx_status *rx_status)
@@ -6808,6 +6831,15 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
        elems = ieee802_11_parse_elems_full(&parse_params);
        if (!elems)
                return;
+
+       if (rx_status->flag & RX_FLAG_DECRYPTED &&
+           ieee80211_mgd_ssid_mismatch(sdata, elems)) {
+               sdata_info(sdata, "SSID mismatch for AP %pM, disconnect\n",
+                          sdata->vif.cfg.ap_addr);
+               __ieee80211_disconnect(sdata);
+               return;
+       }
+
        ncrc = elems->crc;
 
        if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&