diff options
author | Jay Satiro <raysatiro@yahoo.com> | 2021-11-02 15:34:04 -0400 |
---|---|---|
committer | Jay Satiro <raysatiro@yahoo.com> | 2021-11-02 15:34:04 -0400 |
commit | 90e74206b98180b7a185d83d6d20071190e2df59 (patch) | |
tree | 7573204026287c8c2cf655562d3a5197af5b6926 | |
parent | f5ee9cf5baaaeace5a05475553ea8142d9eca123 (diff) | |
download | curl-90e74206b98180b7a185d83d6d20071190e2df59.tar.gz |
schannel: fix memory leak due to failed SSL connection
- Call schannel_shutdown if the SSL connection fails.
Prior to this change schannel_shutdown (which shuts down the SSL
connection as well as memory cleanup) was not called when the SSL
connection failed (eg due to failed handshake).
Co-authored-by: Gisle Vanem
Fixes https://github.com/curl/curl/issues/7877
Closes https://github.com/curl/curl/pull/7878
-rw-r--r-- | lib/vtls/schannel.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index ef3c919bb..44c59e779 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -716,8 +716,6 @@ schannel_acquire_credential_handle(struct Curl_easy *data, } BACKEND->cred->refcount = 1; - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx - */ sspi_status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, @@ -1141,8 +1139,6 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(!host_name) return CURLE_OUT_OF_MEMORY; - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx - */ sspi_status = s_pSecFn->InitializeSecurityContext( &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle, host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL, @@ -2125,26 +2121,23 @@ static bool schannel_data_pending(const struct connectdata *conn, return FALSE; } -static void schannel_close(struct Curl_easy *data, struct connectdata *conn, - int sockindex) -{ - if(conn->ssl[sockindex].use) - /* if the SSL/TLS channel hasn't been shut down yet, do that now. */ - Curl_ssl_shutdown(data, conn, sockindex); -} - static void schannel_session_free(void *ptr) { /* this is expected to be called under sessionid lock */ struct Curl_schannel_cred *cred = ptr; - cred->refcount--; - if(cred->refcount == 0) { - s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); - Curl_safefree(cred); + if(cred) { + cred->refcount--; + if(cred->refcount == 0) { + s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); + Curl_safefree(cred); + } } } +/* shut down the SSL connection and clean up related memory. + this function can be called multiple times on the same connection including + if the SSL connection failed (eg connection made but failed handshake). */ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, int sockindex) { @@ -2156,10 +2149,12 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, DEBUGASSERT(data); - infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu", - hostname, conn->remote_port); + if(connssl->use) { + infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu", + hostname, conn->remote_port); + } - if(BACKEND->cred && BACKEND->ctxt) { + if(connssl->use && BACKEND->cred && BACKEND->ctxt) { SecBufferDesc BuffDesc; SecBuffer Buffer; SECURITY_STATUS sspi_status; @@ -2252,6 +2247,16 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, return CURLE_OK; } +static void schannel_close(struct Curl_easy *data, struct connectdata *conn, + int sockindex) +{ + if(conn->ssl[sockindex].use) + /* Curl_ssl_shutdown resets the socket state and calls schannel_shutdown */ + Curl_ssl_shutdown(data, conn, sockindex); + else + schannel_shutdown(data, conn, sockindex); +} + static int schannel_init(void) { return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0); |