From a86078c876130cf0cca8ef4275f8898a854877b3 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 2 Nov 2020 17:26:04 +0200 Subject: [PATCH] TDLS: Fix error path handling for TPK M1 send failures Local allocation error or failure to get a random number could have resulted in the peer entry getting freed and couple of the error path cases in callers could have tried to reference or delete the peer after that. Fix this by tracking the errors where the peer is freed. Signed-off-by: Jouni Malinen --- src/rsn_supp/tdls.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index eff8cd829..1fb28c5c5 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -1155,7 +1155,7 @@ skip_rsnie: rbuf = os_zalloc(buf_len + 1); if (rbuf == NULL) { wpa_tdls_peer_free(sm, peer); - return -1; + return -2; } pos = rbuf; @@ -1174,7 +1174,7 @@ skip_rsnie: "TDLS: Failed to get random data for initiator Nonce"); os_free(rbuf); wpa_tdls_peer_free(sm, peer); - return -1; + return -2; } peer->tk_set = 0; /* A new nonce results in a new TK */ wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", @@ -1926,7 +1926,8 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, peer->initiator = 1; wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0); - wpa_tdls_send_tpk_m1(sm, peer); + if (wpa_tdls_send_tpk_m1(sm, peer) == -2) + goto error; } if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) && @@ -2654,6 +2655,7 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) { struct wpa_tdls_peer *peer; int tdls_prohibited = sm->tdls_prohibited; + int res; if (sm->tdls_disabled || !sm->tdls_supported) return -1; @@ -2693,8 +2695,10 @@ int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr) peer->tpk_in_progress = 1; - if (wpa_tdls_send_tpk_m1(sm, peer) < 0) { - wpa_tdls_disable_peer_link(sm, peer); + res = wpa_tdls_send_tpk_m1(sm, peer); + if (res < 0) { + if (res != -2) + wpa_tdls_disable_peer_link(sm, peer); return -1; }