Skip to content

Commit 015b8cc

Browse files
alexw65500jmberg-intel
authored andcommitted
wifi: cfg80211: Fix use after free for wext
Key information in wext.connect is not reset on (re)connect and can hold data from a previous connection. Reset key data to avoid that drivers or mac80211 incorrectly detect a WEP connection request and access the freed or already reused memory. Additionally optimize cfg80211_sme_connect() and avoid an useless schedule of conn_work. Fixes: fffd093 ("cfg80211: rework key operation") Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexander Wetzel <[email protected]> Signed-off-by: Johannes Berg <[email protected]>
1 parent 9a47c1e commit 015b8cc

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

net/wireless/sme.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ void cfg80211_conn_work(struct work_struct *work)
285285
wiphy_unlock(&rdev->wiphy);
286286
}
287287

288+
static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
289+
struct cfg80211_bss *bss)
290+
{
291+
memcpy(conn->bssid, bss->bssid, ETH_ALEN);
292+
conn->params.bssid = conn->bssid;
293+
conn->params.channel = bss->channel;
294+
conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
295+
}
296+
288297
/* Returned bss is reference counted and must be cleaned up appropriately. */
289298
static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
290299
{
@@ -302,10 +311,7 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
302311
if (!bss)
303312
return NULL;
304313

305-
memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
306-
wdev->conn->params.bssid = wdev->conn->bssid;
307-
wdev->conn->params.channel = bss->channel;
308-
wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
314+
cfg80211_step_auth_next(wdev->conn, bss);
309315
schedule_work(&rdev->conn_work);
310316

311317
return bss;
@@ -597,7 +603,12 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
597603
wdev->conn->params.ssid_len = wdev->u.client.ssid_len;
598604

599605
/* see if we have the bss already */
600-
bss = cfg80211_get_conn_bss(wdev);
606+
bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
607+
wdev->conn->params.bssid,
608+
wdev->conn->params.ssid,
609+
wdev->conn->params.ssid_len,
610+
wdev->conn_bss_type,
611+
IEEE80211_PRIVACY(wdev->conn->params.privacy));
601612

602613
if (prev_bssid) {
603614
memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
@@ -608,6 +619,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
608619
if (bss) {
609620
enum nl80211_timeout_reason treason;
610621

622+
cfg80211_step_auth_next(wdev->conn, bss);
611623
err = cfg80211_conn_do_work(wdev, &treason);
612624
cfg80211_put_bss(wdev->wiphy, bss);
613625
} else {
@@ -1464,6 +1476,15 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
14641476
} else {
14651477
if (WARN_ON(connkeys))
14661478
return -EINVAL;
1479+
1480+
/* connect can point to wdev->wext.connect which
1481+
* can hold key data from a previous connection
1482+
*/
1483+
connect->key = NULL;
1484+
connect->key_len = 0;
1485+
connect->key_idx = 0;
1486+
connect->crypto.cipher_group = 0;
1487+
connect->crypto.n_ciphers_pairwise = 0;
14671488
}
14681489

14691490
wdev->connect_keys = connkeys;

0 commit comments

Comments
 (0)