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:
parent
5b57c54416
commit
73029dca5a
34
lib/ssluse.c
34
lib/ssluse.c
@ -123,6 +123,10 @@
|
|||||||
#define X509_STORE_set_flags(x,y) Curl_nop_stmt
|
#define X509_STORE_set_flags(x,y) Curl_nop_stmt
|
||||||
#endif
|
#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
|
* 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
|
* a finite value (because some entropy "files" like /dev/urandom have
|
||||||
@ -697,21 +701,28 @@ int Curl_ossl_init(void)
|
|||||||
/* Global cleanup */
|
/* Global cleanup */
|
||||||
void Curl_ossl_cleanup(void)
|
void Curl_ossl_cleanup(void)
|
||||||
{
|
{
|
||||||
/* Free the SSL error strings */
|
/* Free ciphers and digests lists */
|
||||||
ERR_free_strings();
|
|
||||||
|
|
||||||
/* EVP_cleanup() removes all ciphers and digests from the table. */
|
|
||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
|
|
||||||
#ifdef HAVE_ENGINE_CLEANUP
|
#ifdef HAVE_ENGINE_CLEANUP
|
||||||
|
/* Free engine list */
|
||||||
ENGINE_cleanup();
|
ENGINE_cleanup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||||
/* this function was not present in 0.9.6b, but was added sometimes
|
/* Free OpenSSL ex_data table */
|
||||||
later */
|
|
||||||
CRYPTO_cleanup_all_ex_data();
|
CRYPTO_cleanup_all_ex_data();
|
||||||
#endif
|
#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)
|
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
|
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||||
if(data->state.engine) {
|
if(data->state.engine) {
|
||||||
ENGINE_finish(data->state.engine);
|
ENGINE_finish(data->state.engine);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user