aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2019-03-18 19:40:17 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-03-18 19:40:17 +0000
commit1bbc2f1635783b56921eba476697edacab284838 (patch)
treece7637347a46902898679759f310961cb82a0c0f
parent8a6c2503ce9ff19c4d92d40be4a5a65989166ca2 (diff)
parent0f8669c41ca6005697e5743b326608b49e31027f (diff)
downloadwpa_supplicant_8-1bbc2f1635783b56921eba476697edacab284838.tar.gz
Merge "[wpa_supplicant] Cumulative security patch for clearing keys" into pi-dev
-rw-r--r--src/drivers/driver_nl80211.c16
-rw-r--r--src/eap_peer/eap_fast.c28
-rw-r--r--src/eap_peer/eap_peap.c42
-rw-r--r--src/eap_peer/eap_ttls.c44
-rw-r--r--wpa_supplicant/config_file.c2
5 files changed, 72 insertions, 60 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 2ce03ed7..260ec4a6 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -40,6 +40,9 @@
#include "driver_nl80211.h"
+#ifndef NETLINK_CAP_ACK
+#define NETLINK_CAP_ACK 10
+#endif /* NETLINK_CAP_ACK */
#ifndef CONFIG_LIBNL20
/*
* libnl 1.1 has a bug, it tries to allocate socket numbers densely
@@ -339,6 +342,7 @@ static int send_and_recv(struct nl80211_global *global,
{
struct nl_cb *cb;
int err = -ENOMEM;
+ int opt;
if (!msg)
return -ENOMEM;
@@ -347,6 +351,11 @@ static int send_and_recv(struct nl80211_global *global,
if (!cb)
goto out;
+ /* try to set NETLINK_CAP_ACK to 1, ignoring errors */
+ opt = 1;
+ setsockopt(nl_socket_get_fd(nl_handle), SOL_NETLINK,
+ NETLINK_CAP_ACK, &opt, sizeof(opt));
+
err = nl_send_auto_complete(nl_handle, msg);
if (err < 0)
goto out;
@@ -5420,7 +5429,8 @@ skip_auth_type:
if (ret)
goto fail;
- ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
+
msg = NULL;
if (ret) {
wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
@@ -5431,6 +5441,7 @@ skip_auth_type:
}
fail:
+ nl80211_nlmsg_clear(msg);
nlmsg_free(msg);
return ret;
@@ -7576,11 +7587,12 @@ static int nl80211_pmkid(struct i802_bss *bss, int cmd,
params->fils_cache_id)) ||
(params->pmk_len &&
nla_put(msg, NL80211_ATTR_PMK, params->pmk_len, params->pmk))) {
+ nl80211_nlmsg_clear(msg);
nlmsg_free(msg);
return -ENOBUFS;
}
- return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
+ return send_and_recv_msgs(bss->drv, msg, NULL, (void *) -1);
}
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 74cec7dd..94ce57d6 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -250,8 +250,8 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv)
os_memset(data->key_data, 0, EAP_FAST_KEY_LEN);
os_memset(data->emsk, 0, EAP_EMSK_LEN);
os_free(data->session_id);
- wpabuf_free(data->pending_phase2_req);
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_resp);
os_free(data);
}
@@ -486,7 +486,7 @@ static int eap_fast_phase2_request(struct eap_sm *sm,
(config->pending_req_identity || config->pending_req_password ||
config->pending_req_otp || config->pending_req_new_password ||
config->pending_req_sim)) {
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
} else if (*resp == NULL)
return -1;
@@ -801,7 +801,7 @@ static struct wpabuf * eap_fast_process_crypto_binding(
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
data->phase2_success = 0;
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return NULL;
}
@@ -815,7 +815,7 @@ static struct wpabuf * eap_fast_process_crypto_binding(
} else {
wpa_printf(MSG_ERROR, "EAP-FAST: Failed to derive "
"Session-Id");
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return NULL;
}
}
@@ -1150,7 +1150,7 @@ static int eap_fast_encrypt_response(struct eap_sm *sm,
wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
"frame");
}
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return 0;
}
@@ -1328,14 +1328,14 @@ continue_req:
wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
"TLV frame (len=%lu)",
(unsigned long) wpabuf_len(in_decrypted));
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return -1;
}
res = eap_fast_process_decrypted(sm, data, ret, identifier,
in_decrypted, out_data);
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return res;
}
@@ -1613,7 +1613,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
if (sm->waiting_ext_cert_check) {
wpa_printf(MSG_DEBUG,
"EAP-FAST: Waiting external server certificate validation");
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = resp;
return NULL;
}
@@ -1641,7 +1641,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
"EAP-FAST: Could not derive keys");
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return NULL;
}
}
@@ -1650,7 +1650,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
/*
* Application data included in the handshake message.
*/
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = resp;
resp = NULL;
res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp);
@@ -1658,7 +1658,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
}
if (res == 1) {
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return eap_peer_tls_build_ack(id, EAP_TYPE_FAST,
data->fast_version);
}
@@ -1684,9 +1684,9 @@ static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv)
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
os_free(data->key_block_p);
data->key_block_p = NULL;
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = NULL;
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = NULL;
}
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 34075b1d..d2b7d92c 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -186,9 +186,9 @@ static void eap_peap_deinit(struct eap_sm *sm, void *priv)
eap_peer_tls_ssl_deinit(sm, &data->ssl);
eap_peap_free_key(data);
os_free(data->session_id);
- wpabuf_free(data->pending_phase2_req);
- wpabuf_free(data->pending_resp);
- os_free(data);
+ wpabuf_clear_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_resp);
+ bin_clear_free(data, sizeof(*data));
}
@@ -382,7 +382,7 @@ static struct wpabuf * eap_tlv_build_result(struct eap_sm *sm,
wpabuf_put_be16(msg, status); /* Status */
if (crypto_tlv_used && eap_tlv_add_cryptobinding(sm, data, msg)) {
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
return NULL;
}
@@ -651,11 +651,11 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
if (*resp == NULL) {
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
- wpabuf_free(buf);
+ wpabuf_clear_free(buf);
return -1;
}
wpabuf_put_buf(*resp, buf);
- wpabuf_free(buf);
+ wpabuf_clear_free(buf);
break;
}
}
@@ -728,7 +728,7 @@ static int eap_peap_phase2_request(struct eap_sm *sm,
(config->pending_req_identity || config->pending_req_password ||
config->pending_req_otp || config->pending_req_new_password ||
config->pending_req_sim)) {
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
}
@@ -807,7 +807,7 @@ continue_req:
struct wpabuf *nmsg = wpabuf_alloc(sizeof(struct eap_hdr) +
wpabuf_len(in_decrypted));
if (nmsg == NULL) {
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return 0;
}
nhdr = wpabuf_put(nmsg, sizeof(*nhdr));
@@ -817,7 +817,7 @@ continue_req:
nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
wpabuf_len(in_decrypted));
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
in_decrypted = nmsg;
}
@@ -826,7 +826,7 @@ continue_req:
wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
"EAP frame (len=%lu)",
(unsigned long) wpabuf_len(in_decrypted));
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return 0;
}
len = be_to_host16(hdr->length);
@@ -835,7 +835,7 @@ continue_req:
"Phase 2 EAP frame (len=%lu hdr->length=%lu)",
(unsigned long) wpabuf_len(in_decrypted),
(unsigned long) len);
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return 0;
}
if (len < wpabuf_len(in_decrypted)) {
@@ -852,7 +852,7 @@ continue_req:
case EAP_CODE_REQUEST:
if (eap_peap_phase2_request(sm, data, ret, in_decrypted,
&resp)) {
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
wpa_printf(MSG_INFO, "EAP-PEAP: Phase2 Request "
"processing failed");
return 0;
@@ -872,7 +872,7 @@ continue_req:
"completed successfully");
ret->methodState = METHOD_DONE;
ret->decision = DECISION_FAIL;
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return 0;
}
wpa_printf(MSG_DEBUG, "EAP-PEAP: Version 1 - "
@@ -882,7 +882,7 @@ continue_req:
ret->methodState = METHOD_DONE;
data->phase2_success = 1;
if (data->peap_outer_success == 2) {
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
wpa_printf(MSG_DEBUG, "EAP-PEAP: Use TLS ACK "
"to finish authentication");
return 1;
@@ -928,7 +928,7 @@ continue_req:
break;
}
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
if (resp) {
int skip_change2 = 0;
@@ -955,7 +955,7 @@ continue_req:
wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt "
"a Phase 2 frame");
}
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
}
return 0;
@@ -1056,7 +1056,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
if (sm->waiting_ext_cert_check) {
wpa_printf(MSG_DEBUG,
"EAP-PEAP: Waiting external server certificate validation");
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = resp;
return NULL;
}
@@ -1131,7 +1131,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
/*
* Application data included in the handshake message.
*/
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = resp;
resp = NULL;
res = eap_peap_decrypt(sm, data, ret, req, &msg,
@@ -1144,7 +1144,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
}
if (res == 1) {
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return eap_peer_tls_build_ack(id, EAP_TYPE_PEAP,
data->peap_version);
}
@@ -1168,9 +1168,9 @@ static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv)
if (data->phase2_priv && data->phase2_method &&
data->phase2_method->deinit_for_reauth)
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = NULL;
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = NULL;
data->crypto_binding_used = 0;
}
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index f18788ce..5d267010 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -196,8 +196,8 @@ static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
eap_peer_tls_ssl_deinit(sm, &data->ssl);
eap_ttls_free_key(data);
os_free(data->session_id);
- wpabuf_free(data->pending_phase2_req);
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_resp);
os_free(data);
}
@@ -248,7 +248,7 @@ static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
if (msg == NULL) {
- wpabuf_free(*resp);
+ wpabuf_clear_free(*resp);
*resp = NULL;
return -1;
}
@@ -258,7 +258,7 @@ static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
pos += wpabuf_len(*resp);
AVP_PAD(avp, pos);
- wpabuf_free(*resp);
+ wpabuf_clear_free(*resp);
wpabuf_put(msg, pos - avp);
*resp = msg;
return 0;
@@ -510,7 +510,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
challenge = eap_ttls_implicit_challenge(
sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
if (challenge == NULL) {
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
"implicit challenge");
return -1;
@@ -529,7 +529,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
*pos++ = 0; /* Flags */
if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
os_free(challenge);
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
"random data for peer challenge");
return -1;
@@ -543,7 +543,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
peer_challenge, pos, data->auth_response,
data->master_key)) {
os_free(challenge);
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
"response");
return -1;
@@ -604,7 +604,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
challenge = eap_ttls_implicit_challenge(
sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
if (challenge == NULL) {
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
"implicit challenge");
return -1;
@@ -628,7 +628,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
if (challenge_response(challenge, password, pos)) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/MSCHAP: Failed derive password hash");
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
os_free(challenge);
return -1;
}
@@ -641,7 +641,7 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
pos)) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/MSCHAP: Failed derive password");
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
os_free(challenge);
return -1;
}
@@ -760,7 +760,7 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
challenge = eap_ttls_implicit_challenge(
sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
if (challenge == NULL) {
- wpabuf_free(msg);
+ wpabuf_clear_free(msg);
wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
"implicit challenge");
return -1;
@@ -1073,10 +1073,10 @@ static int eap_ttls_encrypt_response(struct eap_sm *sm,
resp, out_data)) {
wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
"frame");
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return -1;
}
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return 0;
}
@@ -1297,7 +1297,7 @@ static int eap_ttls_process_decrypted(struct eap_sm *sm,
config->pending_req_otp ||
config->pending_req_new_password ||
config->pending_req_sim) {
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = wpabuf_dup(in_decrypted);
}
@@ -1340,7 +1340,7 @@ static int eap_ttls_implicit_identity_request(struct eap_sm *sm,
* processing when EAP request is re-processed after
* user input.
*/
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = wpabuf_alloc(0);
}
@@ -1413,7 +1413,7 @@ static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
in_decrypted = data->pending_phase2_req;
data->pending_phase2_req = NULL;
if (wpabuf_len(in_decrypted) == 0) {
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
return eap_ttls_implicit_identity_request(
sm, data, ret, identifier, out_data);
}
@@ -1449,7 +1449,7 @@ continue_req:
&parse, in_decrypted, out_data);
done:
- wpabuf_free(in_decrypted);
+ wpabuf_clear_free(in_decrypted);
os_free(parse.eapdata);
if (retval < 0) {
@@ -1509,7 +1509,7 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
if (sm->waiting_ext_cert_check) {
wpa_printf(MSG_DEBUG,
"EAP-TTLS: Waiting external server certificate validation");
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = *out_data;
*out_data = NULL;
return 0;
@@ -1543,7 +1543,7 @@ static int eap_ttls_process_handshake(struct eap_sm *sm,
/*
* Application data included in the handshake message.
*/
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = *out_data;
*out_data = NULL;
res = eap_ttls_decrypt(sm, data, ret, identifier, in_data,
@@ -1646,7 +1646,7 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
/* FIX: what about res == -1? Could just move all error processing into
* the other functions and get rid of this res==1 case here. */
if (res == 1) {
- wpabuf_free(resp);
+ wpabuf_clear_free(resp);
return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
data->ttls_version);
}
@@ -1669,9 +1669,9 @@ static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
if (data->phase2_priv && data->phase2_method &&
data->phase2_method->deinit_for_reauth)
data->phase2_method->deinit_for_reauth(sm, data->phase2_priv);
- wpabuf_free(data->pending_phase2_req);
+ wpabuf_clear_free(data->pending_phase2_req);
data->pending_phase2_req = NULL;
- wpabuf_free(data->pending_resp);
+ wpabuf_clear_free(data->pending_resp);
data->pending_resp = NULL;
data->decision_succ = DECISION_FAIL;
#ifdef EAP_TNC
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 1fd432d1..25fecd60 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -482,7 +482,7 @@ static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
if (value == NULL)
return;
fprintf(f, "\t%s=%s\n", field, value);
- os_free(value);
+ str_clear_free(value);
}