diff options
author | Yang Tse <yangsita@gmail.com> | 2011-11-04 13:08:37 +0100 |
---|---|---|
committer | Yang Tse <yangsita@gmail.com> | 2011-11-04 13:08:37 +0100 |
commit | 73029dca5aacef7083a41e61c9e0842c012c452c (patch) | |
tree | 2e22e15b66be04d348d7cf91a7f6c6ee4e105228 | |
parent | 5b57c544161987e7deb651110fff4f34a8b0c1ca (diff) |
ssluse.c: fix calling of OpenSSL's ERR_remove_state(0)
Move calling of ERR_remove_state(0) a.k.a ERR_remove_thread_state(NULL)
from Curl_ossl_close_all() to Curl_ossl_cleanup().
In this way ERR_remove_state(0) is now only called in libcurl by
curl_global_cleanup(). Previously it would get called by functions
curl_easy_cleanup(), curl_multi_cleanup and potentially each time a
connection was removed from a connection cache leading to premature
destruction of OpenSSL's thread local state hash.
Multi-threaded apps using OpenSSL enabled libcurl should still call
function ERR_remove_state(0) or ERR_remove_thread_state(NULL) at the
very end end of threads that do not call curl_global_cleanup().
-rw-r--r-- | lib/ssluse.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/lib/ssluse.c b/lib/ssluse.c index d65fd98b9..af70fe08b 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -123,6 +123,10 @@ #define X509_STORE_set_flags(x,y) Curl_nop_stmt #endif +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#define HAVE_ERR_REMOVE_THREAD_STATE 1 +#endif + /* * Number of bytes to read from the random number seed file. This must be * a finite value (because some entropy "files" like /dev/urandom have @@ -697,21 +701,28 @@ int Curl_ossl_init(void) /* Global cleanup */ void Curl_ossl_cleanup(void) { - /* Free the SSL error strings */ - ERR_free_strings(); - - /* EVP_cleanup() removes all ciphers and digests from the table. */ + /* Free ciphers and digests lists */ EVP_cleanup(); #ifdef HAVE_ENGINE_CLEANUP + /* Free engine list */ ENGINE_cleanup(); #endif #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA - /* this function was not present in 0.9.6b, but was added sometimes - later */ + /* Free OpenSSL ex_data table */ CRYPTO_cleanup_all_ex_data(); #endif + + /* Free OpenSSL error strings */ + ERR_free_strings(); + + /* Free thread local error state, destroying hash upon zero refcount */ +#ifdef HAVE_ERR_REMOVE_THREAD_STATE + ERR_remove_thread_state(NULL); +#else + ERR_remove_state(0); +#endif } /* @@ -960,17 +971,6 @@ void Curl_ossl_session_free(void *ptr) */ int Curl_ossl_close_all(struct SessionHandle *data) { - /* - ERR_remove_state() frees the error queue associated with - thread pid. If pid == 0, the current thread will have its - error queue removed. - - Since error queue data structures are allocated - automatically for new threads, they must be freed when - threads are terminated in oder to avoid memory leaks. - */ - ERR_remove_state(0); - #ifdef HAVE_OPENSSL_ENGINE_H if(data->state.engine) { ENGINE_finish(data->state.engine); |