diff --git a/lib/creds.c b/lib/creds.c index d22c166a42..5507ae86f6 100644 --- a/lib/creds.c +++ b/lib/creds.c @@ -46,6 +46,7 @@ CURLcode Curl_creds_create(const char *user, size_t salen = sasl_authzid ? strlen(sasl_authzid) : 0; size_t sslen = sasl_service ? strlen(sasl_service) : 0; char *s, *buf; + size_t bufsize; CURLcode result = CURLE_OK; Curl_creds_unlink(pcreds); @@ -64,13 +65,14 @@ CURLcode Curl_creds_create(const char *user, } /* null-terminator for user already part of struct */ - creds = curlx_calloc(1, sizeof(*creds) + - ulen + plen + 1 + olen + 1 + salen + 1 + sslen + 1); + bufsize = ulen + plen + 1 + olen + 1 + salen + 1 + sslen + 1; + creds = curlx_calloc(1, sizeof(*creds) + bufsize); if(!creds) { result = CURLE_OUT_OF_MEMORY; goto out; } + creds->bufsize = bufsize; creds->refcount = 1; creds->source = source; /* Some compilers try to be too smart about our dynamic struct size */ @@ -147,6 +149,7 @@ void Curl_creds_unlink(struct Curl_creds **pcreds) if(creds->refcount) creds->refcount--; if(!creds->refcount) { + curlx_memzero(creds, sizeof(*creds) + creds->bufsize); curlx_free(creds); } } diff --git a/lib/creds.h b/lib/creds.h index 4a469d69f6..5db3f8f22e 100644 --- a/lib/creds.h +++ b/lib/creds.h @@ -39,6 +39,7 @@ struct Curl_creds { const char *sasl_service; /* non-NULL, maybe empty string */ uint32_t refcount; uint8_t source; /* CREDS_* value */ + size_t bufsize; /* extra bytes added to sizeof(struct Curl_creds) */ char buf[1]; }; diff --git a/lib/curl_share.c b/lib/curl_share.c index 94469bc3ef..b7c331adf7 100644 --- a/lib/curl_share.c +++ b/lib/curl_share.c @@ -34,6 +34,9 @@ static void share_destroy(struct Curl_share *share) { + if(!share) + return; + if(share->specifier & (1 << CURL_LOCK_DATA_CONNECT)) { Curl_cpool_destroy(&share->cpool); } @@ -61,7 +64,7 @@ static void share_destroy(struct Curl_share *share) #ifdef USE_MUTEX Curl_mutex_destroy(&share->lock); #endif - share->magic = 0; + curlx_memzero(share, sizeof(*share)); curlx_free(share); } diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 1429f7143a..5b4e6e41fd 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -100,6 +100,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, xcharp_u domain, dup_domain; xcharp_u passwd, dup_passwd; size_t domlen = 0; + size_t pwlen; domain.const_tchar_ptr = _TEXT(""); @@ -157,17 +158,20 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, curlx_free(dup_domain.tchar_ptr); return CURLE_OUT_OF_MEMORY; } + pwlen = _tcslen(passwd.tchar_ptr); dup_passwd.tchar_ptr = curlx_tcsdup(passwd.tchar_ptr); if(!dup_passwd.tchar_ptr) { curlx_free(dup_user.tchar_ptr); curlx_free(dup_domain.tchar_ptr); + curlx_memzero(passwd.tchar_ptr, pwlen * sizeof(*passwd.tchar_ptr)); curlx_free(passwd.tchar_ptr); return CURLE_OUT_OF_MEMORY; } identity->Password = dup_passwd.tbyte_ptr; - identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); + identity->PasswordLength = curlx_uztoul(pwlen); dup_passwd.tchar_ptr = NULL; + curlx_memzero(passwd.tchar_ptr, pwlen * sizeof(*passwd.tchar_ptr)); curlx_free(passwd.tchar_ptr); identity->User = dup_user.tbyte_ptr; @@ -201,6 +205,8 @@ void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY_EX *identity) { if(identity) { curlx_safefree(identity->User); + curlx_memzero(identity->Password, + identity->PasswordLength * sizeof(*identity->Password)); curlx_safefree(identity->Password); curlx_safefree(identity->Domain); } diff --git a/lib/imap.c b/lib/imap.c index 8f0c297715..cb8f7e8cca 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -613,6 +613,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data, passwd ? passwd : ""); curlx_free(user); + curlx_strzero(passwd); curlx_free(passwd); if(!result) diff --git a/lib/mqtt.c b/lib/mqtt.c index 0858fd65f6..29e92ce5c1 100644 --- a/lib/mqtt.c +++ b/lib/mqtt.c @@ -347,8 +347,10 @@ static CURLcode mqtt_connect(struct Curl_easy *data) result = mqtt_send(data, packet, packetlen); end: - if(packet) + if(packet) { + curlx_memzero(packet, packetlen); curlx_free(packet); + } Curl_creds_unlink(&data->state.creds); return result; } diff --git a/lib/multi.c b/lib/multi.c index f68124436f..e402be099c 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -3060,6 +3060,7 @@ CURLMcode curl_multi_cleanup(CURLM *m) Curl_uint32_bset_destroy(&multi->pending); Curl_uint32_bset_destroy(&multi->msgsent); Curl_uint32_tbl_destroy(&multi->xfers); + curlx_memzero(multi, sizeof(*multi)); curlx_free(multi); mresult = CURLM_OK; diff --git a/lib/setopt.c b/lib/setopt.c index a030b5489e..427cce07af 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -154,6 +154,7 @@ static CURLcode setstropt_userpwd(const char *option, char **userp, curlx_free(*userp); *userp = user; + curlx_strzero(*passwdp); curlx_free(*passwdp); *passwdp = passwd; @@ -1668,6 +1669,7 @@ static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option, result = Curl_urldecode(p, 0, &s->str[STRING_PROXYPASSWORD], NULL, REJECT_ZERO); curlx_free(u); + curlx_strzero(p); curlx_free(p); break; } diff --git a/lib/url.c b/lib/url.c index 5cc5ab7ce9..6dff5102cc 100644 --- a/lib/url.c +++ b/lib/url.c @@ -153,6 +153,15 @@ void Curl_freeset(struct Curl_easy *data) enum dupblob j; for(i = (enum dupstring)0; i < STRING_LAST; i++) { + if(i == STRING_PASSWORD || + i == STRING_KEY_PASSWD || +#ifndef CURL_DISABLE_PROXY + i == STRING_PROXYPASSWORD || + i == STRING_KEY_PASSWD_PROXY || +#endif + i == STRING_BEARER) { + curlx_strzero(data->set.str[i]); + } curlx_safefree(data->set.str[i]); } @@ -301,6 +310,7 @@ CURLcode Curl_close(struct Curl_easy **datap) #ifndef CURL_DISABLE_PROXY Curl_ssl_config_cleanup(&data->set.proxy_ssl.primary); #endif + curlx_memzero(data, sizeof(*data)); curlx_free(data); return CURLE_OK; } diff --git a/lib/urlapi.c b/lib/urlapi.c index 35251053ad..b4dfdda678 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -73,6 +73,7 @@ static void free_urlhandle(struct Curl_URL *u) { curlx_free(u->scheme); curlx_free(u->user); + curlx_strzero(u->password); curlx_free(u->password); curlx_free(u->options); curlx_free(u->host); @@ -325,6 +326,7 @@ UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u, } if(passwdp) { + curlx_strzero(u->password); curlx_free(u->password); u->password = passwdp; } @@ -341,6 +343,7 @@ UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u, out: curlx_free(userp); + curlx_strzero(passwdp); curlx_free(passwdp); curlx_free(optionsp); curlx_safefree(u->user); @@ -1808,6 +1811,7 @@ static CURLUcode urlset_clear(CURLU *u, CURLUPart what) curlx_safefree(u->user); break; case CURLUPART_PASSWORD: + curlx_strzero(u->password); curlx_safefree(u->password); break; case CURLUPART_OPTIONS: @@ -2084,6 +2088,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if(status) return status; + if(what == CURLUPART_PASSWORD) + curlx_strzero(*storep); curlx_free(*storep); *storep = (char *)CURL_UNCONST(newp); } diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index 5423944a29..1ece583595 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -139,7 +139,9 @@ static void free_config_fields(struct OperationConfig *config) curlx_safefree(config->proxy_key); curlx_safefree(config->key_type); curlx_safefree(config->proxy_key_type); + curlx_strzero(config->key_passwd); curlx_safefree(config->key_passwd); + curlx_strzero(config->proxy_key_passwd); curlx_safefree(config->proxy_key_passwd); curlx_safefree(config->pubkey); curlx_safefree(config->hostpubmd5); @@ -152,6 +154,7 @@ static void free_config_fields(struct OperationConfig *config) curlx_safefree(config->request_target); curlx_safefree(config->customrequest); curlx_safefree(config->krblevel); + curlx_strzero(config->oauth_bearer); curlx_safefree(config->oauth_bearer); curlx_safefree(config->sasl_authzid); curlx_safefree(config->unix_socket_path);