wifi: mac80211: mlme: fix null-ptr deref on failed assoc
authorJohannes Berg <johannes.berg@intel.com>
Wed, 21 Sep 2022 00:44:58 +0000 (02:44 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:01 +0000 (13:32 +0100)
[ Upstream commit 78a6a43aaf87180ec7425a2a90468e1b4d09a1ec ]

If association to an AP without a link 0 fails, then we crash in
tracing because it assumes that either ap_mld_addr or link 0 BSS
is valid, since we clear sdata->vif.valid_links and then don't
add the ap_mld_addr to the struct.

Since we clear also sdata->vif.cfg.ap_addr, keep a local copy of
it and assign it earlier, before clearing valid_links, to fix
this.

Fixes: 81151ce462e5 ("wifi: mac80211: support MLO authentication/association with one link")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/mac80211/mlme.c

index d8484cd..1fff44d 100644 (file)
@@ -5033,6 +5033,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_rx_assoc_resp resp = {
                .uapsd_queues = -1,
        };
+       u8 ap_mld_addr[ETH_ALEN] __aligned(2);
        unsigned int link_id;
 
        sdata_assert_lock(sdata);
@@ -5199,6 +5200,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                                resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
        }
 
+       if (sdata->vif.valid_links) {
+               ether_addr_copy(ap_mld_addr, sdata->vif.cfg.ap_addr);
+               resp.ap_mld_addr = ap_mld_addr;
+       }
+
        ieee80211_destroy_assoc_data(sdata,
                                     status_code == WLAN_STATUS_SUCCESS ?
                                        ASSOC_SUCCESS :
@@ -5208,8 +5214,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        resp.len = len;
        resp.req_ies = ifmgd->assoc_req_ies;
        resp.req_ies_len = ifmgd->assoc_req_ies_len;
-       if (sdata->vif.valid_links)
-               resp.ap_mld_addr = sdata->vif.cfg.ap_addr;
        cfg80211_rx_assoc_resp(sdata->dev, &resp);
 notify_driver:
        drv_mgd_complete_tx(sdata->local, sdata, &info);