From patchwork Wed May 16 00:30:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Stewart X-Patchwork-Id: 159797 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "maxx.shmoo.com", Issuer "CA Cert Signing Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 08133B6FB7 for ; Thu, 17 May 2012 11:08:36 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id DCDF09D2DC; Wed, 16 May 2012 21:08:32 -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 Tf+oMBpaLKIH; Wed, 16 May 2012 21:08:32 -0400 (EDT) Received: from maxx.shmoo.com (localhost [127.0.0.1]) by maxx.maxx.shmoo.com (Postfix) with ESMTP id 364EC9D2F6; Wed, 16 May 2012 21:08:25 -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 D0AD49D2F5 for ; Wed, 16 May 2012 21:08:23 -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 c0njhEEVKNSg for ; Wed, 16 May 2012 21:08:20 -0400 (EDT) Received: from mail-wg0-f74.google.com (mail-wg0-f74.google.com [74.125.82.74]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by maxx.maxx.shmoo.com (Postfix) with ESMTPS id BE9949D2DC for ; Wed, 16 May 2012 21:08:19 -0400 (EDT) Received: by wgbdt11 with SMTP id dt11so79753wgb.5 for ; Wed, 16 May 2012 18:08:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:date:subject:to:cc:message-id:x-gm-message-state; bh=Ja4rqDkVjEWosYKAY7AIjF9EvFlD7I0+LZUgD7ygirM=; b=hQQ2gNtcV9eEdj78pgFU7PiiNFWlEDnSVQ/F/i01c2bELJjn8dsUj73TvVUIMw69yt wxXNb0iE4j/AKCzPr80QCn1Ua8fp26dxUX2mM+juupRACfUY0Mmk1nhmIe0+mFyeXIeK 0vzyn5swtJ+IlWvqrgnxfNp4xDGaY7YkTY/6fvBHeS6IEX7KhCNPTljn53FXevMhNXiF DfJYR5rZzRa8ZIVjZpNtyLVm4/8CR18+u5Tkbep8kS8ANppFy4KBABIr+Af0IeSNmPrJ UhWqEZdKBze++xILpZuWlR9dFNcWL/yVU6Q9PSznk1Zog3D06f5uGQ7NJxBNm0jC++r6 MXaA== Received: by 10.14.99.75 with SMTP id w51mr1109762eef.8.1337216898281; Wed, 16 May 2012 18:08:18 -0700 (PDT) Received: by 10.14.99.75 with SMTP id w51mr1109756eef.8.1337216898164; Wed, 16 May 2012 18:08:18 -0700 (PDT) Received: from hpza9.eem.corp.google.com ([74.125.121.33]) by gmr-mx.google.com with ESMTPS id d52si4013438eei.1.2012.05.16.18.08.18 (version=TLSv1/SSLv3 cipher=AES128-SHA); Wed, 16 May 2012 18:08:18 -0700 (PDT) Received: from glenhelen.mtv.corp.google.com (glenhelen.mtv.corp.google.com [172.22.72.223]) by hpza9.eem.corp.google.com (Postfix) with ESMTP id C2B905C0050; Wed, 16 May 2012 18:08:17 -0700 (PDT) Received: by glenhelen.mtv.corp.google.com (Postfix, from userid 110058) id 014922074C; Wed, 16 May 2012 18:08:16 -0700 (PDT) From: Paul Stewart Date: Tue, 15 May 2012 17:30:56 -0700 Subject: [PATCH] bss: Don't remove a BSS that is in use To: hostap@lists.shmoo.com Message-Id: <20120517010817.014922074C@glenhelen.mtv.corp.google.com> X-Gm-Message-State: ALoCoQkQAJTPmODNz9Qbnyn6sk+eJynRZyDu9Sn/wiEL/2HuiuXUx49EAyAwwuDL2IpDFgAiqFgZbCXW5/XrpfxNZILzdjkiQTTiK7dukttRSx2lf5aaxu//Gifi4rbnHIB2JY/EAjVWpt3cNXaLZYAQz7V/gUVX5W+3PGMRBcdiUJj8PNi3/1Q= Cc: Jouni Malinen X-BeenThere: hostap@lists.shmoo.com X-Mailman-Version: 2.1.9 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 When looking for a BSS to eject due to too many entries, never not pick one that is in use. Otherwise, we run the risk of having pointers to freed data. Signed-off-by: Paul Stewart Cc: Jouni Malinen --- wpa_supplicant/bss.c | 63 ++++++++++++++++++++++++++++--------------------- 1 files changed, 36 insertions(+), 27 deletions(-) diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index a373116..12b311f 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -35,14 +35,15 @@ #define WPA_BSS_IES_CHANGED_FLAG BIT(8) -static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, + const char *reason) { dl_list_del(&bss->list); dl_list_del(&bss->list_id); wpa_s->num_bss--; wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR - " SSID '%s'", bss->id, MAC2STR(bss->bssid), - wpa_ssid_txt(bss->ssid, bss->ssid_len)); + " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid), + wpa_ssid_txt(bss->ssid, bss->ssid_len), reason); wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id); #ifdef CONFIG_INTERWORKING wpabuf_free(bss->anqp_venue_name); @@ -120,13 +121,21 @@ static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) } +static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +{ + return bss == wpa_s->current_bss || + os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 || + os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0; +} + + static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (!wpa_bss_known(wpa_s, bss)) { - wpa_bss_remove(wpa_s, bss); + wpa_bss_remove(wpa_s, bss, __func__); return 0; } } @@ -135,21 +144,28 @@ static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s) } -static void wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) +static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) { + struct wpa_bss *bss; + /* * Remove the oldest entry that does not match with any configured * network. */ if (wpa_bss_remove_oldest_unknown(wpa_s) == 0) - return; + return 0; /* - * Remove the oldest entry since no better candidate for removal was - * found. + * Remove the oldest entry that isn't currently in use. */ - wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss, - struct wpa_bss, list)); + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (!wpa_bss_in_use(wpa_s, bss)) { + wpa_bss_remove(wpa_s, bss, __func__); + return 0; + } + } + + return -1; } @@ -178,8 +194,13 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s, " SSID '%s'", bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len)); wpas_notify_bss_added(wpa_s, bss->bssid, bss->id); - if (wpa_s->num_bss > wpa_s->conf->bss_max_count) - wpa_bss_remove_oldest(wpa_s); + if (wpa_s->num_bss > wpa_s->conf->bss_max_count && + wpa_bss_remove_oldest(wpa_s) != 0) { + wpa_printf(MSG_ERROR, "Increasing the MAX BSS count " + " to %d because all BSSes are in use. We should " + " normally not get here!", wpa_s->num_bss); + wpa_s->conf->bss_max_count = wpa_s->num_bss; + } } @@ -350,14 +371,6 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } -static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) -{ - return bss == wpa_s->current_bss || - os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 || - os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0; -} - - void wpa_bss_update_start(struct wpa_supplicant *wpa_s) { wpa_s->bss_update_idx++; @@ -469,9 +482,7 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, bss->scan_miss_count++; if (bss->scan_miss_count >= wpa_s->conf->bss_expiration_scan_count) { - wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Expire BSS %u due to " - "no match in scan", bss->id); - wpa_bss_remove(wpa_s, bss); + wpa_bss_remove(wpa_s, bss, "no match in scan"); } } } @@ -493,9 +504,7 @@ void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age) continue; if (os_time_before(&bss->last_update, &t)) { - wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Expire BSS %u due to " - "age", bss->id); - wpa_bss_remove(wpa_s, bss); + wpa_bss_remove(wpa_s, bss, __func__); } else break; } @@ -532,7 +541,7 @@ void wpa_bss_flush(struct wpa_supplicant *wpa_s) dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; - wpa_bss_remove(wpa_s, bss); + wpa_bss_remove(wpa_s, bss, __func__); } }