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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-07-02 01:45:45 +03:00
parent d1ecca6c15
commit b7175b4d02
4 changed files with 17 additions and 13 deletions

View file

@ -379,7 +379,7 @@ void hostapd_config_free_eap_user(struct hostapd_eap_user *user)
{ {
hostapd_config_free_radius_attr(user->accept_attr); hostapd_config_free_radius_attr(user->accept_attr);
os_free(user->identity); os_free(user->identity);
os_free(user->password); bin_clear_free(user->password, user->password_len);
os_free(user); os_free(user);
} }
@ -388,7 +388,7 @@ static void hostapd_config_free_wep(struct hostapd_wep_keys *keys)
{ {
int i; int i;
for (i = 0; i < NUM_WEP_KEYS; 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; keys->key[i] = NULL;
} }
} }
@ -406,10 +406,10 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
while (psk) { while (psk) {
prev = psk; prev = psk;
psk = psk->next; 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); os_free(conf->ssid.wpa_psk_file);
hostapd_config_free_wep(&conf->ssid.wep); hostapd_config_free_wep(&conf->ssid.wep);
#ifdef CONFIG_FULL_DYNAMIC_VLAN #ifdef CONFIG_FULL_DYNAMIC_VLAN

View file

@ -83,7 +83,7 @@ static int get_user_cb(void *ctx, int argc, char *argv[], char *col[])
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if (os_strcmp(col[i], "password") == 0 && argv[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_len = os_strlen(argv[i]);
user->password = (u8 *) os_strdup(argv[i]); user->password = (u8 *) os_strdup(argv[i]);
user->next = (void *) 1; 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 && if (len <= user->identity_len &&
os_memcmp(argv[id], user->identity, len) == 0 && os_memcmp(argv[id], user->identity, len) == 0 &&
(user->password == NULL || len > user->password_len)) { (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_len = os_strlen(argv[id]);
user->password = (u8 *) os_strdup(argv[id]); user->password = (u8 *) os_strdup(argv[id]);
user->next = (void *) 1; user->next = (void *) 1;
@ -158,8 +158,10 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity,
return NULL; return NULL;
} }
os_free(hapd->tmp_eap_user.identity); bin_clear_free(hapd->tmp_eap_user.identity,
os_free(hapd->tmp_eap_user.password); 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)); os_memset(&hapd->tmp_eap_user, 0, sizeof(hapd->tmp_eap_user));
hapd->tmp_eap_user.phase2 = phase2; hapd->tmp_eap_user.phase2 = phase2;
hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1); hapd->tmp_eap_user.identity = os_zalloc(identity_len + 1);

View file

@ -311,8 +311,10 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
#endif /* CONFIG_INTERWORKING */ #endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_SQLITE #ifdef CONFIG_SQLITE
os_free(hapd->tmp_eap_user.identity); bin_clear_free(hapd->tmp_eap_user.identity,
os_free(hapd->tmp_eap_user.password); hapd->tmp_eap_user.identity_len);
bin_clear_free(hapd->tmp_eap_user.password,
hapd->tmp_eap_user.password_len);
#endif /* CONFIG_SQLITE */ #endif /* CONFIG_SQLITE */
} }

View file

@ -623,7 +623,7 @@ radius_server_get_new_session(struct radius_server_data *data,
os_memset(&tmp, 0, sizeof(tmp)); os_memset(&tmp, 0, sizeof(tmp));
res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &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) { if (res != 0) {
RADIUS_DEBUG("User-Name not found from user database"); 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); os_strlen(sess->username), 0, &tmp);
if (res || !tmp.macacl || tmp.password == NULL) { if (res || !tmp.macacl || tmp.password == NULL) {
RADIUS_DEBUG("No MAC ACL user entry"); RADIUS_DEBUG("No MAC ACL user entry");
os_free(tmp.password); bin_clear_free(tmp.password, tmp.password_len);
code = RADIUS_CODE_ACCESS_REJECT; code = RADIUS_CODE_ACCESS_REJECT;
} else { } else {
u8 buf[128]; u8 buf[128];
@ -861,7 +861,7 @@ radius_server_macacl(struct radius_server_data *data,
(u8 *) client->shared_secret, (u8 *) client->shared_secret,
client->shared_secret_len, client->shared_secret_len,
buf, sizeof(buf)); buf, sizeof(buf));
os_free(tmp.password); bin_clear_free(tmp.password, tmp.password_len);
if (res < 0 || pw_len != (size_t) res || if (res < 0 || pw_len != (size_t) res ||
os_memcmp_const(pw, buf, res) != 0) { os_memcmp_const(pw, buf, res) != 0) {