From bb218c395a970e1c404bddf3cc28140d79e1c274 Mon Sep 17 00:00:00 2001
From: ppescher
Date: Mon, 29 Nov 2021 15:34:02 +0100
Subject: [PATCH] Fix memory leaks when SSL/TLS connection fails
---
libraries/WiFiClientSecure/src/ssl_client.cpp | 20 +++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp
index c910206b3c9..38783aee2e4 100644
--- a/libraries/WiFiClientSecure/src/ssl_client.cpp
+++ b/libraries/WiFiClientSecure/src/ssl_client.cpp
@@ -45,6 +45,8 @@ static int _handle_error(int err, const char * function, int line)
void ssl_init(sslclient_context *ssl_client)
{
+ // reset embedded pointers to zero
+ memset(ssl_client, 0, sizeof(sslclient_context));
mbedtls_ssl_init(&ssl_client->ssl_ctx);
mbedtls_ssl_config_init(&ssl_client->ssl_conf);
mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx);
@@ -232,6 +234,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0);
if (ret != 0) {
+ mbedtls_x509_crt_free(&ssl_client->client_cert); // cert+key are free'd in pair
return handle_error(ret);
}
@@ -243,7 +246,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
// Hostname set here should match CN in server certificate
if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0){
return handle_error(ret);
- }
+ }
mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx);
@@ -260,8 +263,8 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
return handle_error(ret);
}
if((millis()-handshake_start_time)>ssl_client->handshake_timeout)
- return -1;
- vTaskDelay(2);//2 ticks
+ return -1;
+ vTaskDelay(2);//2 ticks
}
@@ -280,7 +283,6 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
memset(buf, 0, sizeof(buf));
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
log_e("Failed to verify peer certificate! verification info: %s", buf);
- stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
return handle_error(ret);
} else {
log_v("Certificate verified.");
@@ -313,10 +315,20 @@ void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, cons
ssl_client->socket = -1;
}
+ // avoid memory leak if ssl connection attempt failed
+ if (ssl_client->ssl_conf.ca_chain != NULL) {
+ mbedtls_x509_crt_free(&ssl_client->ca_cert);
+ }
+ if (ssl_client->ssl_conf.key_cert != NULL) {
+ mbedtls_x509_crt_free(&ssl_client->client_cert);
+ mbedtls_pk_free(&ssl_client->client_key);
+ }
mbedtls_ssl_free(&ssl_client->ssl_ctx);
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
mbedtls_entropy_free(&ssl_client->entropy_ctx);
+ // reset embedded pointers to zero
+ memset(ssl_client, 0, sizeof(sslclient_context));
}