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().
This commit is contained in:
Yang Tse 2011-11-04 13:08:37 +01:00
parent 5b57c54416
commit 73029dca5a

View File

@ -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);