From f29f4485b56b8aab1bb9ecc9094fbfbfe5bedc32 Mon Sep 17 00:00:00 2001 From: Paolo Messina Date: Tue, 14 Dec 2021 14:59:26 +0100 Subject: [PATCH] Fix memory leaks when SSL/TLS connection fails (#5945) --- 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 c910206b3..38783aee2 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)); } -- GitLab