From 04949598a23f501be6eec21697465fd46a28840a Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Thu, 19 Jul 2012 12:16:46 -0700 Subject: wpa_supplicant: Update to 07-Jul-2012 TOT commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4 Author: Jouni Malinen Date: Sat Jul 7 13:01:45 2012 +0300 WPS SSDP: Fix socket leaks on error paths Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85 Signed-off-by: Dmitry Shmidt --- wpa_supplicant/bss.c | 87 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 27 deletions(-) (limited to 'wpa_supplicant/bss.c') diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index cbed2e0..580a82a 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); @@ -53,6 +54,12 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) wpabuf_free(bss->anqp_3gpp); wpabuf_free(bss->anqp_domain_name); #endif /* CONFIG_INTERWORKING */ +#ifdef CONFIG_HS20 + wpabuf_free(bss->hs20_operator_friendly_name); + wpabuf_free(bss->hs20_wan_metrics); + wpabuf_free(bss->hs20_connection_capability); + wpabuf_free(bss->hs20_operating_class); +#endif /* CONFIG_HS20 */ os_free(bss); } @@ -61,6 +68,8 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid, size_t ssid_len) { struct wpa_bss *bss; + if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid)) + return NULL; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && bss->ssid_len == ssid_len && @@ -112,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; } } @@ -127,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; } @@ -170,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!", (int) wpa_s->num_bss); + wpa_s->conf->bss_max_count = wpa_s->num_bss; + } } @@ -326,6 +355,8 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, nbss = os_realloc(bss, sizeof(*bss) + res->ie_len + res->beacon_ie_len); if (nbss) { + if (wpa_s->current_bss == bss) + wpa_s->current_bss = nbss; bss = nbss; os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len); @@ -340,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++; @@ -375,6 +398,18 @@ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, } p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE); +#ifdef CONFIG_P2P + if (p2p == NULL && + wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { + /* + * If it's a P2P specific interface, then don't update + * the scan result without a P2P IE. + */ + wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR + " update for P2P interface", MAC2STR(res->bssid)); + return; + } +#endif /* CONFIG_P2P */ if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN && os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0) return; /* Skip P2P listen discovery results here */ @@ -447,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"); } } } @@ -471,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; } @@ -510,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__); } } @@ -526,6 +557,8 @@ struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid) { struct wpa_bss *bss; + if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid)) + return NULL; dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) { if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) return bss; -- cgit v1.1