From ae149ff43b011ac616c26062b77a0661bb956502 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 29 Sep 2018 11:19:45 -0700 Subject: [PATCH] Really free stack after last BearSSL obj destroyed The BearSSL second stack, once allocated, was never deallocated. The reference count of the stack pointer never hit 0 due to the initial creation counting as one. Now, check to see if there is only one use_count and if so then delete the stack. --- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 16 ++++++++++++++-- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 276514ab91..3fc7ff0930 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -91,12 +91,16 @@ WiFiClientSecure::WiFiClientSecure() : WiFiClient() { _clear(); _clearAuthenticationSettings(); _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived + _ensureStackAvailable(); + _local_bearssl_stack = _bearssl_stack; +} + +void WiFiClientSecure::_ensureStackAvailable() { if (!_bearssl_stack) { const int stacksize = 4500; // Empirically determined stack for EC and RSA connections _bearssl_stack = std::shared_ptr(new uint8_t[stacksize], std::default_delete()); br_esp8266_stack_proxy_init(_bearssl_stack.get(), stacksize); } - _local_bearssl_stack = _bearssl_stack; } WiFiClientSecure::~WiFiClientSecure() { @@ -106,7 +110,11 @@ WiFiClientSecure::~WiFiClientSecure() { } free(_cipher_list); _freeSSL(); - _local_bearssl_stack = nullptr; // Potentially delete it if we're the last SSL object + _local_bearssl_stack = nullptr; + // If there are no other uses than the initial creation, free the stack + if (_bearssl_stack.use_count() == 1) { + _bearssl_stack = nullptr; + } if (_deleteChainKeyTA) { delete _ta; delete _chain; @@ -119,6 +127,8 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client, int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta) { _clear(); _clearAuthenticationSettings(); + _ensureStackAvailable(); + _local_bearssl_stack = _bearssl_stack; _iobuf_in_size = iobuf_in_size; _iobuf_out_size = iobuf_out_size; _client = client; @@ -136,6 +146,8 @@ WiFiClientSecure::WiFiClientSecure(ClientContext *client, int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta) { _clear(); _clearAuthenticationSettings(); + _ensureStackAvailable(); + _local_bearssl_stack = _bearssl_stack; _iobuf_in_size = iobuf_in_size; _iobuf_out_size = iobuf_out_size; _client = client; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index af32a38ee1..143258276a 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -229,6 +229,7 @@ class WiFiClientSecure : public WiFiClient { private: // Single memory buffer used for BearSSL auxilliary stack, insead of growing main Arduino stack for all apps static std::shared_ptr _bearssl_stack; + void _ensureStackAvailable(); // Allocate the stack if necessary // The local copy, only used to enable a reference count std::shared_ptr _local_bearssl_stack; };