diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2019-03-18 19:40:17 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-03-18 19:40:17 +0000 |
commit | 1bbc2f1635783b56921eba476697edacab284838 (patch) | |
tree | ce7637347a46902898679759f310961cb82a0c0f | |
parent | 8a6c2503ce9ff19c4d92d40be4a5a65989166ca2 (diff) | |
parent | 0f8669c41ca6005697e5743b326608b49e31027f (diff) | |
download | wpa_supplicant_8-1bbc2f1635783b56921eba476697edacab284838.tar.gz |
Merge "[wpa_supplicant] Cumulative security patch for clearing keys" into pi-dev
-rw-r--r-- | src/drivers/driver_nl80211.c | 16 | ||||
-rw-r--r-- | src/eap_peer/eap_fast.c | 28 | ||||
-rw-r--r-- | src/eap_peer/eap_peap.c | 42 | ||||
-rw-r--r-- | src/eap_peer/eap_ttls.c | 44 | ||||
-rw-r--r-- | wpa_supplicant/config_file.c | 2 |
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); } |