From f0bfbe2a6c2ac33918bc1166a6c15a32e08006e1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 27 Jan 2011 14:06:17 +0200 Subject: [PATCH] TDLS: Replace os_memset() of all peer data with safer approach Blindly clearing all struct wpa_tdls_peer members is a risky operation since it could easily clear pointers to allocated memory, etc. information that really should not be removed. Instead of hoping that new code gets added here to restore the important variables, reverse the approach and only clear structure members one by one when needed. --- src/rsn_supp/tdls.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index f84139df8..f2baa04f9 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -248,26 +248,6 @@ static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code, } -static void tdls_clear_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer) -{ - u8 mac[ETH_ALEN]; - struct wpa_tdls_peer *tmp; - - os_memcpy(mac, peer->addr, ETH_ALEN); - tmp = peer->next; - peer->initiator = 0; - eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer); - os_free(peer->sm_tmr.buf); - - /* reset all */ - os_memset(peer, 0, sizeof(*peer)); - - /* restore things */ - os_memcpy(peer->addr, mac, ETH_ALEN); - peer->next = tmp; -} - - static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx) { @@ -598,11 +578,19 @@ static void wpa_tdls_tpk_timeout(void *eloop_ctx, void *timeout_ctx) static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer) { + wpa_printf(MSG_DEBUG, "TDLS: Clear state for peer " MACSTR, + MAC2STR(peer->addr)); eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer); - - /* need to clear Peerkey SM */ - tdls_clear_peer(sm, peer); - //os_free(peer); + eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer); + peer->initiator = 0; + os_free(peer->sm_tmr.buf); + peer->sm_tmr.buf = NULL; + peer->rsnie_i_len = peer->rsnie_p_len = 0; + peer->cipher = 0; + peer->tpk_set = peer->tpk_success = 0; + os_memset(&peer->tpk, 0, sizeof(peer->tpk)); + os_memset(peer->inonce, 0, WPA_NONCE_LEN); + os_memset(peer->rnonce, 0, WPA_NONCE_LEN); }