diff --git a/src/bin/util/softhsm2-util.cpp b/src/bin/util/softhsm2-util.cpp index c3975819f..24469f9ba 100644 --- a/src/bin/util/softhsm2-util.cpp +++ b/src/bin/util/softhsm2-util.cpp @@ -74,22 +74,22 @@ #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif diff --git a/src/lib/SoftHSM.cpp b/src/lib/SoftHSM.cpp index e5cd0cab5..0f97688f3 100644 --- a/src/lib/SoftHSM.cpp +++ b/src/lib/SoftHSM.cpp @@ -105,25 +105,25 @@ #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif -std::unique_ptr SoftHSM::instance(nullptr); +std::unique_ptr* SoftHSM::instance = new std::unique_ptr(); #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif -std::auto_ptr SoftHSM::instance(NULL); +std::auto_ptr* SoftHSM::instance = new std::auto_ptr(); #endif @@ -411,11 +411,11 @@ static void resetMutexFactoryCallbacks() // Return the one-and-only instance SoftHSM* SoftHSM::i() { - if (!instance.get()) + if (!instance->get()) { - instance.reset(new SoftHSM()); + instance->reset(new SoftHSM()); } - else if(instance->detectFork()) + else if((*instance)->detectFork()) { if (Configuration::i()->getBool("library.reset_on_fork", false)) { @@ -424,18 +424,18 @@ SoftHSM* SoftHSM::i() * the old instance is first destroyed as some * static structures are erased in the destructor. */ - instance.reset(NULL); - instance.reset(new SoftHSM()); + instance->reset(NULL); + instance->reset(new SoftHSM()); } } - return instance.get(); + return instance->get(); } void SoftHSM::reset() { - if (instance.get()) - instance.reset(); + if (instance->get()) + instance->reset(); } // Constructor diff --git a/src/lib/SoftHSM.h b/src/lib/SoftHSM.h index 724812c91..f7970b789 100644 --- a/src/lib/SoftHSM.h +++ b/src/lib/SoftHSM.h @@ -201,11 +201,30 @@ class SoftHSM // Constructor SoftHSM(); - // The one-and-only instance + // The one-and-only instance. + // + // Smart pointers must not be used directly as class-level + // static storage: their destructor runs as part of the C++ + // runtime's ordinary static-object teardown at process exit, an + // indeterminate time relative to unrelated code's own cleanup + // (see the "Static and Global Variables" section of the Google + // C++ Style Guide, which explicitly recommends "a pointer that + // is never freed" for exactly this situation). Concretely here: + // a PKCS#11 caller (e.g. a provider) may still be closing its + // own open sessions via C_CloseSession() when this destructor + // fires, and would then be operating on an already-destroyed + // singleton. + // + // The smart pointer itself is therefore heap-allocated once and + // deliberately never freed - the same "leaky singleton" idiom + // used by e.g. Drake's never_destroyed - while still using it + // (not a raw pointer) to own and manage the SoftHSM object's own + // lifetime, which is destroyed exactly once, only via the + // explicit C_Finalize()/reset() path below. #ifdef HAVE_CXX11 - static std::unique_ptr instance; + static std::unique_ptr* instance; #else - static std::auto_ptr instance; + static std::auto_ptr* instance; #endif // Is the SoftHSM PKCS #11 library initialised? diff --git a/src/lib/common/MutexFactory.cpp b/src/lib/common/MutexFactory.cpp index 1cfc0dab2..61eeebf1f 100644 --- a/src/lib/common/MutexFactory.cpp +++ b/src/lib/common/MutexFactory.cpp @@ -111,12 +111,12 @@ MutexFactory::~MutexFactory() // Return the one-and-only instance MutexFactory* MutexFactory::i() { - if (!instance.get()) + if (!instance->get()) { - instance.reset(new MutexFactory()); + instance->reset(new MutexFactory()); } - return instance.get(); + return instance->get(); } // Get a mutex instance diff --git a/src/lib/common/MutexFactory.h b/src/lib/common/MutexFactory.h index 167dc3dbe..3e4ff6894 100644 --- a/src/lib/common/MutexFactory.h +++ b/src/lib/common/MutexFactory.h @@ -112,11 +112,15 @@ class MutexFactory CK_RV LockMutex(CK_VOID_PTR mutex); CK_RV UnlockMutex(CK_VOID_PTR mutex); - // The one-and-only instance + // The one-and-only instance. + // + // A pointer to a heap-allocated, deliberately never-freed smart + // pointer, not a smart pointer directly: see the rationale + // beside SoftHSM::instance in SoftHSM.h. #ifdef HAVE_CXX11 - static std::unique_ptr instance; + static std::unique_ptr* instance; #else - static std::auto_ptr instance; + static std::auto_ptr* instance; #endif // The function pointers diff --git a/src/lib/crypto/BotanCryptoFactory.cpp b/src/lib/crypto/BotanCryptoFactory.cpp index 4ad743df8..93ac4da02 100644 --- a/src/lib/crypto/BotanCryptoFactory.cpp +++ b/src/lib/crypto/BotanCryptoFactory.cpp @@ -89,18 +89,18 @@ BotanCryptoFactory::~BotanCryptoFactory() // Return the one-and-only instance BotanCryptoFactory* BotanCryptoFactory::i() { - if (!instance.get()) + if (!instance->get()) { - instance.reset(new BotanCryptoFactory()); + instance->reset(new BotanCryptoFactory()); } - return instance.get(); + return instance->get(); } // This will destroy the one-and-only instance. void BotanCryptoFactory::reset() { - instance.reset(); + instance->reset(); } // Create a concrete instance of a symmetric algorithm diff --git a/src/lib/crypto/BotanCryptoFactory.h b/src/lib/crypto/BotanCryptoFactory.h index 788ae373d..bc05188f7 100644 --- a/src/lib/crypto/BotanCryptoFactory.h +++ b/src/lib/crypto/BotanCryptoFactory.h @@ -81,11 +81,15 @@ class BotanCryptoFactory : public CryptoFactory // Constructor BotanCryptoFactory(); - // The one-and-only instance + // The one-and-only instance. + // + // A pointer to a heap-allocated, deliberately never-freed smart + // pointer, not a smart pointer directly: see the rationale + // beside SoftHSM::instance in SoftHSM.h. #ifdef HAVE_CXX11 - static std::unique_ptr instance; + static std::unique_ptr* instance; #else - static std::auto_ptr instance; + static std::auto_ptr* instance; #endif // Thread specific RNG diff --git a/src/lib/crypto/OSSLCryptoFactory.cpp b/src/lib/crypto/OSSLCryptoFactory.cpp index c46d0dde1..0143ee29c 100644 --- a/src/lib/crypto/OSSLCryptoFactory.cpp +++ b/src/lib/crypto/OSSLCryptoFactory.cpp @@ -294,18 +294,18 @@ OSSLCryptoFactory::~OSSLCryptoFactory() // Return the one-and-only instance OSSLCryptoFactory* OSSLCryptoFactory::i() { - if (!instance.get()) + if (!instance->get()) { - instance.reset(new OSSLCryptoFactory()); + instance->reset(new OSSLCryptoFactory()); } - return instance.get(); + return instance->get(); } // This will destroy the one-and-only instance. void OSSLCryptoFactory::reset() { - instance.reset(); + instance->reset(); } #ifdef WITH_FIPS diff --git a/src/lib/crypto/OSSLCryptoFactory.h b/src/lib/crypto/OSSLCryptoFactory.h index bdfc031bd..cf46fe079 100644 --- a/src/lib/crypto/OSSLCryptoFactory.h +++ b/src/lib/crypto/OSSLCryptoFactory.h @@ -89,11 +89,15 @@ class OSSLCryptoFactory : public CryptoFactory // Constructor OSSLCryptoFactory(); - // The one-and-only instance + // The one-and-only instance. + // + // A pointer to a heap-allocated, deliberately never-freed smart + // pointer, not a smart pointer directly: see the rationale + // beside SoftHSM::instance in SoftHSM.h. #ifdef HAVE_CXX11 - static std::unique_ptr instance; + static std::unique_ptr* instance; #else - static std::auto_ptr instance; + static std::auto_ptr* instance; #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) diff --git a/src/lib/crypto/test/cryptotest.cpp b/src/lib/crypto/test/cryptotest.cpp index 2f8839aba..4ec1b8363 100644 --- a/src/lib/crypto/test/cryptotest.cpp +++ b/src/lib/crypto/test/cryptotest.cpp @@ -56,22 +56,22 @@ // Initialise the one-and-only instance #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif diff --git a/src/lib/data_mgr/SecureMemoryRegistry.cpp b/src/lib/data_mgr/SecureMemoryRegistry.cpp index 57de15668..f658b1d02 100644 --- a/src/lib/data_mgr/SecureMemoryRegistry.cpp +++ b/src/lib/data_mgr/SecureMemoryRegistry.cpp @@ -56,11 +56,11 @@ SecureMemoryRegistry::~SecureMemoryRegistry() // Return the one-and-only instance SecureMemoryRegistry* SecureMemoryRegistry::i() { - if (instance.get() == NULL) + if (instance->get() == NULL) { - instance.reset(new SecureMemoryRegistry()); + instance->reset(new SecureMemoryRegistry()); - if (instance.get() == NULL) + if (instance->get() == NULL) { // This is very bad! ERROR_MSG("failed to instantiate SecureMemoryRegistry"); @@ -68,13 +68,13 @@ SecureMemoryRegistry* SecureMemoryRegistry::i() } } - return instance.get(); + return instance->get(); } // This will destroy the one-and-only instance. void SecureMemoryRegistry::reset() { - instance.reset(); + instance->reset(); } // Register a block of memory diff --git a/src/lib/data_mgr/SecureMemoryRegistry.h b/src/lib/data_mgr/SecureMemoryRegistry.h index 6c733693e..767504741 100644 --- a/src/lib/data_mgr/SecureMemoryRegistry.h +++ b/src/lib/data_mgr/SecureMemoryRegistry.h @@ -58,10 +58,13 @@ class SecureMemoryRegistry void wipe(); private: + // A pointer to a heap-allocated, deliberately never-freed smart + // pointer, not a smart pointer directly: see the rationale + // beside SoftHSM::instance in SoftHSM.h. #ifdef HAVE_CXX11 - static std::unique_ptr instance; + static std::unique_ptr* instance; #else - static std::auto_ptr instance; + static std::auto_ptr* instance; #endif std::map registry; diff --git a/src/lib/data_mgr/test/datamgrtest.cpp b/src/lib/data_mgr/test/datamgrtest.cpp index bf1b836e0..399fe7442 100644 --- a/src/lib/data_mgr/test/datamgrtest.cpp +++ b/src/lib/data_mgr/test/datamgrtest.cpp @@ -53,22 +53,22 @@ // Initialise the one-and-only instance #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif diff --git a/src/lib/handle_mgr/test/handlemgrtest.cpp b/src/lib/handle_mgr/test/handlemgrtest.cpp index e8f300a34..2a73304a3 100644 --- a/src/lib/handle_mgr/test/handlemgrtest.cpp +++ b/src/lib/handle_mgr/test/handlemgrtest.cpp @@ -49,9 +49,9 @@ #include "MutexFactory.h" #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); #else -std::auto_ptr MutexFactory::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); #endif class MyProgressListener : public CppUnit::TextTestProgressListener diff --git a/src/lib/object_store/test/objstoretest.cpp b/src/lib/object_store/test/objstoretest.cpp index 0fa4b4b0b..060adc20c 100644 --- a/src/lib/object_store/test/objstoretest.cpp +++ b/src/lib/object_store/test/objstoretest.cpp @@ -53,22 +53,22 @@ // Initialise the one-and-only instance #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif diff --git a/src/lib/session_mgr/test/sessionmgrtest.cpp b/src/lib/session_mgr/test/sessionmgrtest.cpp index 0ea55fca7..45aace8ee 100644 --- a/src/lib/session_mgr/test/sessionmgrtest.cpp +++ b/src/lib/session_mgr/test/sessionmgrtest.cpp @@ -59,22 +59,22 @@ // Initialise the one-and-only instance #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif diff --git a/src/lib/slot_mgr/test/slotmgrtest.cpp b/src/lib/slot_mgr/test/slotmgrtest.cpp index a70527fe1..10477cff8 100644 --- a/src/lib/slot_mgr/test/slotmgrtest.cpp +++ b/src/lib/slot_mgr/test/slotmgrtest.cpp @@ -53,22 +53,22 @@ // Initialise the one-and-only instance #ifdef HAVE_CXX11 -std::unique_ptr MutexFactory::instance(nullptr); -std::unique_ptr SecureMemoryRegistry::instance(nullptr); +std::unique_ptr* MutexFactory::instance = new std::unique_ptr(); +std::unique_ptr* SecureMemoryRegistry::instance = new std::unique_ptr(); #if defined(WITH_OPENSSL) -std::unique_ptr OSSLCryptoFactory::instance(nullptr); +std::unique_ptr* OSSLCryptoFactory::instance = new std::unique_ptr(); #else -std::unique_ptr BotanCryptoFactory::instance(nullptr); +std::unique_ptr* BotanCryptoFactory::instance = new std::unique_ptr(); #endif #else -std::auto_ptr MutexFactory::instance(NULL); -std::auto_ptr SecureMemoryRegistry::instance(NULL); +std::auto_ptr* MutexFactory::instance = new std::auto_ptr(); +std::auto_ptr* SecureMemoryRegistry::instance = new std::auto_ptr(); #if defined(WITH_OPENSSL) -std::auto_ptr OSSLCryptoFactory::instance(NULL); +std::auto_ptr* OSSLCryptoFactory::instance = new std::auto_ptr(); #else -std::auto_ptr BotanCryptoFactory::instance(NULL); +std::auto_ptr* BotanCryptoFactory::instance = new std::auto_ptr(); #endif #endif