[PATCH] Add helper function to clear and free wpa_psk list

Stefan Tomanek stefan.tomanek at wertarbyte.de
Mon Jan 19 17:57:41 EST 2015


This change adds the function hostapd_config_clear_wpa_psk() that deletes an
entire wpa_psk structure, making sure to follow the linked list and to free the
allocated memory of each PSK node. This helps to prevent memory leaks when
using PSKs from multiple sources and reconfiguring the AP during runtime.

Signed-off-by: Stefan Tomanek <stefan.tomanek at wertarbyte.de>
---
 hostapd/config_file.c |  8 +++-----
 src/ap/ap_config.c    | 16 +++++++++-------
 src/ap/ap_config.h    |  1 +
 src/ap/hostapd.c      |  3 +--
 src/ap/wps_hostapd.c  |  5 ++---
 5 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 99cd052..7fff8b6 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2265,12 +2265,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		os_free(bss->ssid.wpa_passphrase);
 		bss->ssid.wpa_passphrase = os_strdup(pos);
 		if (bss->ssid.wpa_passphrase) {
-			os_free(bss->ssid.wpa_psk);
-			bss->ssid.wpa_psk = NULL;
+			hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
 			bss->ssid.wpa_passphrase_set = 1;
 		}
 	} else if (os_strcmp(buf, "wpa_psk") == 0) {
-		os_free(bss->ssid.wpa_psk);
+		hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
 		bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
 		if (bss->ssid.wpa_psk == NULL)
 			return 1;
@@ -2278,8 +2277,7 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		    pos[PMK_LEN * 2] != '\0') {
 			wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
 				   line, pos);
-			os_free(bss->ssid.wpa_psk);
-			bss->ssid.wpa_psk = NULL;
+			hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
 			return 1;
 		}
 		bss->ssid.wpa_psk->group = 1;
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 1c0ed7a..8aa1002 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -393,21 +393,23 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
 	}
 }
 
+void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **l) {
+	struct hostapd_wpa_psk *psk, *tmp;
+	for (psk = *l; (tmp = psk) != NULL;) {
+		psk = psk->next;
+		bin_clear_free(tmp, sizeof(*tmp));
+	}
+	*l = NULL;
+}
 
 void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 {
-	struct hostapd_wpa_psk *psk, *prev;
 	struct hostapd_eap_user *user, *prev_user;
 
 	if (conf == NULL)
 		return;
 
-	psk = conf->ssid.wpa_psk;
-	while (psk) {
-		prev = psk;
-		psk = psk->next;
-		bin_clear_free(prev, sizeof(*prev));
-	}
+	hostapd_config_clear_wpa_psk(&conf->ssid.wpa_psk);
 
 	str_clear_free(conf->ssid.wpa_passphrase);
 	os_free(conf->ssid.wpa_psk_file);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index e5215c5..a5c7f3c 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -642,6 +642,7 @@ struct hostapd_config {
 #endif /* CONFIG_ACS */
 };
 
+void hostapd_config_clear_wpa_psk(struct hostapd_wpa_psk **p);
 
 int hostapd_mac_comp(const void *a, const void *b);
 int hostapd_mac_comp_empty(const void *a);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index b641503..2d3a52d 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -82,8 +82,7 @@ static void hostapd_reload_bss(struct hostapd_data *hapd)
 		 * Force PSK to be derived again since SSID or passphrase may
 		 * have changed.
 		 */
-		os_free(ssid->wpa_psk);
-		ssid->wpa_psk = NULL;
+		hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
 	}
 	if (hostapd_setup_wpa_psk(hapd->conf)) {
 		wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 9ba7aba..b0e8b0b 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -362,10 +362,9 @@ static int hapd_wps_reconfig_in_memory(struct hostapd_data *hapd,
 			if (bss->ssid.wpa_passphrase)
 				os_memcpy(bss->ssid.wpa_passphrase, cred->key,
 					  cred->key_len);
-			os_free(bss->ssid.wpa_psk);
-			bss->ssid.wpa_psk = NULL;
+			hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
 		} else if (cred->key_len == 64) {
-			os_free(bss->ssid.wpa_psk);
+			hostapd_config_clear_wpa_psk(&bss->ssid.wpa_psk);
 			bss->ssid.wpa_psk =
 				os_zalloc(sizeof(struct hostapd_wpa_psk));
 			if (bss->ssid.wpa_psk &&
-- 
2.1.3


More information about the HostAP mailing list