From 05821a59c4606fc80b4981150389c93f1ac1c58f Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Mon, 27 Sep 2021 18:31:25 +0000 Subject: [PATCH] Locking around SSLSecret::secret_map access This fixes an infrequent crash that would happen in getOrLoadSecret. Looking at the core, the iterators for SSLSecret::secret_map in SSLSecret::getOrLoadSecret were corrupted. This patch serializes access to the structure so that multiple threads don't stomp on each other. --- iocore/net/P_SSLSecret.h | 6 ++++++ iocore/net/SSLSecret.cc | 3 +++ 2 files changed, 9 insertions(+) diff --git a/iocore/net/P_SSLSecret.h b/iocore/net/P_SSLSecret.h index d873efb1faa..f6b2a279421 100644 --- a/iocore/net/P_SSLSecret.h +++ b/iocore/net/P_SSLSecret.h @@ -19,6 +19,11 @@ limitations under the License. */ +#include +#include +#include +#include + class SSLSecret { public: @@ -33,4 +38,5 @@ class SSLSecret bool loadFile(const std::string &name, std::string &data_item); std::unordered_map secret_map; + mutable std::recursive_mutex secret_map_mutex; }; diff --git a/iocore/net/SSLSecret.cc b/iocore/net/SSLSecret.cc index f58ed696b26..945e444a0e0 100644 --- a/iocore/net/SSLSecret.cc +++ b/iocore/net/SSLSecret.cc @@ -72,6 +72,7 @@ SSLSecret::loadFile(const std::string &name, std::string &data_item) bool SSLSecret::setSecret(const std::string &name, const char *data, int data_len) { + std::scoped_lock lock(secret_map_mutex); auto iter = secret_map.find(name); if (iter == secret_map.end()) { secret_map[name] = ""; @@ -88,6 +89,7 @@ SSLSecret::setSecret(const std::string &name, const char *data, int data_len) const std::string * SSLSecret::getSecretItem(const std::string &name) const { + std::scoped_lock lock(secret_map_mutex); auto iter = secret_map.find(name); if (iter == secret_map.end()) { return nullptr; @@ -111,6 +113,7 @@ SSLSecret::getSecret(const std::string &name, std::string_view &data) const bool SSLSecret::getOrLoadSecret(const std::string &name1, const std::string &name2, std::string_view &data1, std::string_view &data2) { + std::scoped_lock lock(secret_map_mutex); bool found_secret1 = this->getSecret(name1, data1); bool found_secret2 = name2.empty() || this->getSecret(name2, data2);