diff --git a/fdbclient/NativeAPI.actor.cpp b/fdbclient/NativeAPI.actor.cpp index 5f379c4f3d..ad61994bdb 100644 --- a/fdbclient/NativeAPI.actor.cpp +++ b/fdbclient/NativeAPI.actor.cpp @@ -994,6 +994,7 @@ void setupNetwork(uint64_t transportId, bool useMetrics) { if (!networkOptions.logClientInfo.present()) networkOptions.logClientInfo = true; + TLS::DisableOpenSSLAtExitHandler(); g_network = newNet2(tlsConfig, false, useMetrics || networkOptions.traceDirectory.present()); FlowTransport::createInstance(true, transportId); Net2FileSystem::newFileSystem(); @@ -1019,6 +1020,7 @@ void stopNetwork() { g_network->stop(); closeTraceFile(); + TLS::DestroyOpenSSLGlobalState(); } Reference DatabaseContext::getMasterProxies(bool useProvisionalProxies) { diff --git a/flow/TLSConfig.actor.cpp b/flow/TLSConfig.actor.cpp index f432229ec9..73a336e38a 100644 --- a/flow/TLSConfig.actor.cpp +++ b/flow/TLSConfig.actor.cpp @@ -25,6 +25,32 @@ // To force typeinfo to only be emitted once. TLSPolicy::~TLSPolicy() {} +namespace TLS { + +void DisableOpenSSLAtExitHandler() { +#ifdef TLS_DISABLED + return; +#else + static bool once = false; + if (!once) { + once = true; + int success = OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, nullptr); + if (!success) { + throw tls_error(); + } + } +#endif +} + +void DestroyOpenSSLGlobalState() { +#ifdef TLS_DISABLED + return; +#else + OPENSSL_cleanup(); +#endif +} + +} // namespace TLS #ifdef TLS_DISABLED void LoadedTLSConfig::print(FILE *fp) { diff --git a/flow/TLSConfig.actor.h b/flow/TLSConfig.actor.h index 820c90d5c9..aa07e27fde 100644 --- a/flow/TLSConfig.actor.h +++ b/flow/TLSConfig.actor.h @@ -36,6 +36,22 @@ #include "flow/Knobs.h" #include "flow/flow.h" +namespace TLS { + +// Force OpenSSL to not register an atexit handler to clean up global state before process exit. +// If you call this, you must also call DestroyOpenSSLGlobalState() before the program exits. +// Calls OPENSSL_init_crypto with OPENSSL_INIT_NO_ATEXIT. +// Must be called before any other OpenSSL function. +void DisableOpenSSLAtExitHandler(); + +// Frees all global state maintained by OpenSSL. +// Calls OPENSSL_cleanup. +// Must be called before program exit if using DisableOpenSSLAtExitHandler. +// No OpenSSL code may be run after calling this function. +void DestroyOpenSSLGlobalState(); + +} // namespace TLS + #ifndef TLS_DISABLED #include