From patchwork Wed Jun 25 14:41:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilan Peer X-Patchwork-Id: 364062 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from maxx.maxx.shmoo.com (maxx.shmoo.com [205.134.188.171]) by ozlabs.org (Postfix) with ESMTP id 1D85A14009B for ; Thu, 26 Jun 2014 01:43:14 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id D8B5A9D2E0; Wed, 25 Jun 2014 11:43:04 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8XSLrhmxtC3y; Wed, 25 Jun 2014 11:43:04 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 04E339D2E2; Wed, 25 Jun 2014 11:42:44 -0400 (EDT) X-Original-To: mailman-post+hostap@maxx.shmoo.com Delivered-To: mailman-post+hostap@maxx.shmoo.com Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 1853A17C018 for ; Wed, 25 Jun 2014 11:42:42 -0400 (EDT) X-Virus-Scanned: amavisd-new at maxx.shmoo.com Received: from maxx.maxx.shmoo.com ([127.0.0.1]) by localhost (maxx.shmoo.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4e1Y08ARNMew for ; Wed, 25 Jun 2014 11:42:35 -0400 (EDT) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 254899D2DF for ; Wed, 25 Jun 2014 11:42:35 -0400 (EDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 25 Jun 2014 08:32:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,546,1400050800"; d="scan'208";a="533984260" Received: from unknown (HELO ipeer-e6430-1.jer.intel.com) ([10.12.217.176]) by orsmga001.jf.intel.com with ESMTP; 25 Jun 2014 08:37:30 -0700 From: Ilan Peer To: hostap@lists.shmoo.com Subject: [PATCH 2/5] TDLS: remove peer from global peer-list on free Date: Wed, 25 Jun 2014 17:41:52 +0300 Message-Id: <1403707315-17613-2-git-send-email-ilan.peer@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1403707315-17613-1-git-send-email-ilan.peer@intel.com> References: <1403707315-17613-1-git-send-email-ilan.peer@intel.com> Cc: Arik Nemtsov , Arik Nemtsov X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.11 Precedence: list List-Id: HostAP Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: hostap-bounces@lists.shmoo.com Errors-To: hostap-bounces@lists.shmoo.com From: Arik Nemtsov Also fix a small bug where a peer was used after free. Signed-off-by: Arik Nemtsov Tested-by: Ilan Peer --- src/rsn_supp/tdls.c | 71 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 0955348..3171248 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -635,7 +635,29 @@ 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) +static void wpa_tdls_peer_remove_from_list(struct wpa_sm *sm, + struct wpa_tdls_peer *peer) +{ + struct wpa_tdls_peer *cur, *prev; + + for (cur = sm->tdls, prev = NULL; cur && cur != peer; + prev = cur, cur = cur->next) + ; + + if (cur != peer) { + wpa_printf(MSG_ERROR, "TDLS: could not find peer " MACSTR, + MAC2STR(peer->addr)); + return; + } + + if (prev) + prev->next = peer->next; + else + sm->tdls = peer->next; +} + + +static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) { wpa_printf(MSG_DEBUG, "TDLS: Clear state for peer " MACSTR, MAC2STR(peer->addr)); @@ -667,6 +689,14 @@ static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer) } +static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer) +{ + wpa_tdls_peer_clear(sm, peer); + wpa_tdls_peer_remove_from_list(sm, peer); + os_free(peer); +} + + static void wpa_tdls_linkid(struct wpa_sm *sm, struct wpa_tdls_peer *peer, struct wpa_tdls_lnkid *lnkid) { @@ -1652,16 +1682,16 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while " "direct link is enabled - tear down the " "old link first"); - wpa_tdls_disable_peer_link(sm, peer); - } - - /* - * An entry is already present, so check if we already sent a - * TDLS Setup Request. If so, compare MAC addresses and let the - * STA with the lower MAC address continue as the initiator. - * The other negotiation is terminated. - */ - if (peer->initiator) { + wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); + wpa_tdls_peer_clear(sm, peer); + } else if (peer->initiator) { + /* + * An entry is already present, so check if we already + * sent a TDLS Setup Request. If so, compare MAC + * addresses and let the STA with the lower MAC address + * continue as the initiator. The other negotiation is + * terminated. + */ if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) { wpa_printf(MSG_DEBUG, "TDLS: Discard request " "from peer with higher address " @@ -1673,7 +1703,9 @@ static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, MACSTR " (terminate previously " "initiated negotiation", MAC2STR(src_addr)); - wpa_tdls_disable_peer_link(sm, peer); + wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, + peer->addr); + wpa_tdls_peer_clear(sm, peer); } } } @@ -1926,7 +1958,7 @@ skip_rsn_check: wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2"); if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) { - wpa_tdls_disable_peer_link(sm, peer); + wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); goto error; } @@ -2234,10 +2266,8 @@ skip_rsn: wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / " "TPK Handshake Message 3"); - if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0) { - wpa_tdls_disable_peer_link(sm, peer); - return -1; - } + if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0) + goto error; if (!peer->tpk_success) { /* @@ -2629,13 +2659,14 @@ int wpa_tdls_init(struct wpa_sm *sm) void wpa_tdls_teardown_peers(struct wpa_sm *sm) { - struct wpa_tdls_peer *peer; + struct wpa_tdls_peer *peer, *tmp; peer = sm->tdls; wpa_printf(MSG_DEBUG, "TDLS: Tear down peers"); while (peer) { + tmp = peer->next; wpa_printf(MSG_DEBUG, "TDLS: Tear down peer " MACSTR, MAC2STR(peer->addr)); if (sm->tdls_external_setup) @@ -2644,7 +2675,7 @@ void wpa_tdls_teardown_peers(struct wpa_sm *sm) else wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr); - peer = peer->next; + peer = tmp; } } @@ -2654,7 +2685,6 @@ static void wpa_tdls_remove_peers(struct wpa_sm *sm) struct wpa_tdls_peer *peer, *tmp; peer = sm->tdls; - sm->tdls = NULL; while (peer) { int res; @@ -2663,7 +2693,6 @@ static void wpa_tdls_remove_peers(struct wpa_sm *sm) wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)", MAC2STR(peer->addr), res); wpa_tdls_peer_free(sm, peer); - os_free(peer); peer = tmp; } }