diff options
author | Johannes Berg <johannes.berg@intel.com> | 2024-06-12 14:38:10 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2024-06-26 10:22:10 +0200 |
commit | 9cc88678db5be1d67c865dbe60afb56867698301 (patch) | |
tree | 73b9db3985969fb86d8bc3b8bc2979058eff128d /net/mac80211 | |
parent | 0b2d9d9aec2be212a28b7d14b5462c56d9adc3a3 (diff) |
wifi: mac80211: check SSID in beacon
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>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/mlme.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e76b887a46eb..3d207d79d11f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -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) && |