diff options
-rw-r--r-- | base/openssl_util.cc | 19 | ||||
-rw-r--r-- | net/base/x509_certificate_openssl.cc | 12 |
2 files changed, 25 insertions, 6 deletions
diff --git a/base/openssl_util.cc b/base/openssl_util.cc index 1cbc304..5cfc34a 100644 --- a/base/openssl_util.cc +++ b/base/openssl_util.cc @@ -22,6 +22,20 @@ unsigned long CurrentThreadId() { // Singleton for initializing and cleaning up the OpenSSL library. class OpenSSLInitSingleton { + public: + static OpenSSLInitSingleton* Get() { + // We allow the SSL environment to leak for multiple reasons: + // - it is used from a non-joinable worker thread that is not stopped on + // shutdown, hence may still be using OpenSSL library after the AtExit + // runner has completed. + // - There are other OpenSSL related singletons (e.g. the client socket + // context) who's cleanup depends on the global environment here, but + // we can't control the order the AtExit handlers will run in so + // allowing the global environment to leak at least ensures it is + // available for those other singletons to reliably cleanup. + return Singleton<OpenSSLInitSingleton, + LeakySingletonTraits<OpenSSLInitSingleton> >::get(); + } private: friend struct DefaultSingletonTraits<OpenSSLInitSingleton>; OpenSSLInitSingleton() { @@ -43,8 +57,7 @@ class OpenSSLInitSingleton { } static void LockingCallback(int mode, int n, const char* file, int line) { - Singleton<OpenSSLInitSingleton>::get()->OnLockingCallback(mode, n, file, - line); + OpenSSLInitSingleton::Get()->OnLockingCallback(mode, n, file, line); } void OnLockingCallback(int mode, int n, const char* file, int line) { @@ -64,7 +77,7 @@ class OpenSSLInitSingleton { } // namespace void EnsureOpenSSLInit() { - (void)Singleton<OpenSSLInitSingleton>::get(); + (void)OpenSSLInitSingleton::Get(); } void ClearOpenSSLERRStack(const tracked_objects::Location& location) { diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc index 2be38dd..d2c7653 100644 --- a/net/base/x509_certificate_openssl.cc +++ b/net/base/x509_certificate_openssl.cc @@ -206,6 +206,13 @@ void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, class X509InitSingleton { public: + static X509InitSingleton* Get() { + // We allow the X509 store to leak, because it is used from a non-joinable + // worker that is not stopped on shutdown, hence may still be using + // OpenSSL library after the AtExit runner has completed. + return Singleton<X509InitSingleton, + LeakySingletonTraits<X509InitSingleton> >::get(); + } int der_cache_ex_index() const { return der_cache_ex_index_; } X509_STORE* store() const { return store_.get(); } @@ -252,8 +259,7 @@ DERCache* SetDERCache(X509Certificate::OSCertHandle cert, // not free it). bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert, DERCache* der_cache) { - int x509_der_cache_index = - Singleton<X509InitSingleton>::get()->der_cache_ex_index(); + int x509_der_cache_index = X509InitSingleton::Get()->der_cache_ex_index(); // Re-encoding the DER data via i2d_X509 is an expensive operation, but it's // necessary for comparing two certificates. We re-encode at most once per @@ -386,7 +392,7 @@ void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { // static X509_STORE* X509Certificate::cert_store() { - return Singleton<X509InitSingleton>::get()->store(); + return X509InitSingleton::Get()->store(); } int X509Certificate::Verify(const std::string& hostname, |