From b7175b4d02d11b5450e9743f1b9728ed6aa2ec23 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 2 Jul 2014 01:45:45 +0300 Subject: [PATCH] Clear hostapd configuration keys explicitly Use an explicit memset call to clear any hostapd configuration parameter that contains private information like keys or identity. This brings in an additional layer of protection by reducing the length of time this type of private data is kept in memory. Signed-off-by: Jouni Malinen --- src/ap/ap_config.c | 8 ++++---- src/ap/eap_user_db.c | 10 ++++++---- src/ap/hostapd.c | 6 ++++-- src/radius/radius_server.c | 6 +++--- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 7535b1b75..bc9f6cf46 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -379,7 +379,7 @@ void hostapd_config_free_eap_user(struct hostapd_eap_user *user) { hostapd_config_free_radius_attr(user->accept_attr); os_free(user->identity); - os_free(user->password); + bin_clear_free(user->password, user->password_len); os_free(user); } @@ -388,7 +388,7 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys) { int i; for (i = 0; i < NUM_WEP_KEYS; i++) { - os_free(keys->key[i]); + bin_clear_free(keys->key[i], keys->len[i]); keys->key[i] = NULL; } } @@ -406,10 +406,10 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) while (psk) { prev = psk; psk = psk->next; - os_free(prev); + bin_clear_free(prev, sizeof(*prev)); } - os_free(conf->ssid.wpa_passphrase); + str_clear_free(conf->ssid.wpa_passphrase); os_free(conf->ssid.wpa_psk_file); hostapd_config_free_wep(&conf->ssid.wep); #ifdef CONFIG_FULL_DYNAMIC_VLAN diff --git a/src/ap/eap_user_db.c b/src/ap/eap_user_db.c index 371a73f2a..559d77f9e 100644 --- a/src/ap/eap_user_db.c +++ b/src/ap/eap_user_db.c @@ -83,7 +83,7 @@ static int get_user_cb(void *ctx, int argc, char *argv[], char *col[]) for (i = 0; i < argc; i++) { if (os_strcmp(col[i], "password") == 0 && argv[i]) { - os_free(user->password); + bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[i]); user->password = (u8 *) os_strdup(argv[i]); user->next = (void *) 1; @@ -118,7 +118,7 @@ static int get_wildcard_cb(void *ctx, int argc, char *argv[], char *col[]) if (len <= user->identity_len && os_memcmp(argv[id], user->identity, len) == 0 && (user->password == NULL || len > user->password_len)) { - os_free(user->password); + bin_clear_free(user->password, user->password_len); user->password_len = os_strlen(argv[id]); user->password = (u8 *) os_strdup(argv[id]); user->next = (void *) 1; @@ -158,8 +158,10 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity, return NULL; } - os_free(hapd->tmp_eap_user.identity); - os_free(hapd->tmp_eap_user.password); + bin_clear_free(hapd->tmp_eap_user.identity, + hapd->tmp_eap_user.identity_len); + bin_clear_free(hapd->tmp_eap_user.password, + hapd->tmp_eap_user.password_len); os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user)); hapd->tmp_eap_user.phase2 = phase2; hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 55b7ced8a..26aca2b05 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -311,8 +311,10 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd) #endif /* CONFIG_INTERWORKING */ #ifdef CONFIG_SQLITE - os_free(hapd->tmp_eap_user.identity); - os_free(hapd->tmp_eap_user.password); + bin_clear_free(hapd->tmp_eap_user.identity, + hapd->tmp_eap_user.identity_len); + bin_clear_free(hapd->tmp_eap_user.password, + hapd->tmp_eap_user.password_len); #endif /* CONFIG_SQLITE */ } diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c index 00ad6af6f..24348a395 100644 --- a/src/radius/radius_server.c +++ b/src/radius/radius_server.c @@ -623,7 +623,7 @@ radius_server_get_new_session(struct radius_server_data *data, os_memset(&tmp, 0, sizeof(tmp)); res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); if (res != 0) { RADIUS_DEBUG("User-Name not found from user database"); @@ -852,7 +852,7 @@ radius_server_macacl(struct radius_server_data *data, os_strlen(sess->username), 0, &tmp); if (res || !tmp.macacl || tmp.password == NULL) { RADIUS_DEBUG("No MAC ACL user entry"); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); code = RADIUS_CODE_ACCESS_REJECT; } else { u8 buf[128]; @@ -861,7 +861,7 @@ radius_server_macacl(struct radius_server_data *data, (u8 *) client->shared_secret, client->shared_secret_len, buf, sizeof(buf)); - os_free(tmp.password); + bin_clear_free(tmp.password, tmp.password_len); if (res < 0 || pw_len != (size_t) res || os_memcmp_const(pw, buf, res) != 0) {