wpa_supplicant segfault in large WLAN

Message ID 20130927144023.GA8151@w1.fi
State Not Applicable
Headers show

Commit Message

Jouni Malinen Sept. 27, 2013, 2:40 p.m.
On Fri, Sep 27, 2013 at 09:16:38AM -0400, Matt Causey wrote:
> I'll do it straight-away.  Thanks for all your help!  Shall I expect these
> patches to apply cleanly to the wpa_supplicant-2.0 release or should we
> migrate to hostap.git HEAD in our stack?

Like you noticed, the second commit did not apply cleanly. That's the
commit that should not really matter for you in practice. Anyway, if
you want to apply these on top of 2.0, you can use the attached patches.


From fec2df6e57e0322eaf3ce4690102aa87aff00ac7 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <jouni@qca.qualcomm.com>
Date: Fri, 27 Sep 2013 16:00:50 +0300
Subject: [PATCH 2/2] Make sure updated BSS entry does not get added twice to
 the list

When the BSS table is being updated based on new scan results, a BSS
entry could end up getting added into last_scan_res list multiple times
if the scan results from the driver includes duplicated values. This
should not happen with driver_nl80211.c since it filter outs duplicates,
but in theory, other driver wrappers could indicate such scan results.
Anyway, it is safer to make sure this cannot happen by explicitly
verifying the last_scan_res list before adding an updated BSS entry
there. A duplicated entry in the list could potentially result in freed
memory being used if there is large enough number of BSSes in the scan
results to cause removal of old BSS entries.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>


 wpa_supplicant/bss.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 06e7064..bb11b03 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -597,8 +597,18 @@  void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
 	bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]);
 	if (bss == NULL)
 		bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res);
-	else
+	else {
 		bss = wpa_bss_update(wpa_s, bss, res);
+		if (wpa_s->last_scan_res) {
+			unsigned int i;
+			for (i = 0; i < wpa_s->last_scan_res_used; i++) {
+				if (bss == wpa_s->last_scan_res[i]) {
+					/* Already in the list */
+					return;
+				}
+			}
+		}
+	}
 	if (bss == NULL)