#include <internal/threads.h>
#include <internal/cryptlib_int.h>
#include <openssl/err.h>
-#include <openssl/rand.h>
+#include <internal/rand.h>
#include <openssl/evp.h>
#include <internal/evp_int.h>
#include <internal/conf.h>
#include <internal/async.h>
-#ifndef OPENSSL_NO_ENGINE
#include <internal/engine.h>
-#endif
-#include <openssl/comp.h>
+#include <internal/comp.h>
#include <internal/err.h>
#include <stdlib.h>
#include <assert.h>
};
static OPENSSL_INIT_STOP *stop_handlers = NULL;
+static CRYPTO_RWLOCK *init_lock = NULL;
static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
static int base_inited = 0;
#ifndef OPENSSL_SYS_UEFI
atexit(OPENSSL_cleanup);
#endif
+ init_lock = CRYPTO_THREAD_lock_new();
OPENSSL_cpuid_setup();
base_inited = 1;
}
config_inited = 1;
}
-#ifndef OPENSSL_NO_ASYNC
static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
static int async_inited = 0;
static void ossl_init_async(void)
async_init();
async_inited = 1;
}
-#endif
#ifndef OPENSSL_NO_ENGINE
-static int engine_inited = 0;
static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
static void ossl_init_engine_openssl(void)
{
"engine_load_openssl_internal()\n");
# endif
engine_load_openssl_internal();
- engine_inited = 1;
}
# if !defined(OPENSSL_NO_HW) && \
(defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
"engine_load_cryptodev_internal()\n");
# endif
engine_load_cryptodev_internal();
- engine_inited = 1;
}
# endif
"engine_load_rdrand_internal()\n");
# endif
engine_load_rdrand_internal();
- engine_inited = 1;
}
# endif
static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
"engine_load_dynamic_internal()\n");
# endif
engine_load_dynamic_internal();
- engine_inited = 1;
}
# ifndef OPENSSL_NO_STATIC_ENGINE
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
"engine_load_padlock_internal()\n");
# endif
engine_load_padlock_internal();
- engine_inited = 1;
}
# endif
# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
"engine_load_capi_internal()\n");
# endif
engine_load_capi_internal();
- engine_inited = 1;
}
# endif
static CRYPTO_ONCE engine_dasync = CRYPTO_ONCE_STATIC_INIT;
"engine_load_dasync_internal()\n");
# endif
engine_load_dasync_internal();
- engine_inited = 1;
}
# if !defined(OPENSSL_NO_AFALGENG)
-static OPENSSL_INIT_ONCE engine_afalg = OPENSSL_INIT_ONCE_STATIC_INIT;
+static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
static void ossl_init_engine_afalg(void)
{
# ifdef OPENSSL_INIT_DEBUG
"engine_load_afalg_internal()\n");
# endif
engine_load_afalg_internal();
- engine_inited = 1;
}
# endif
# endif
#endif
+#ifndef OPENSSL_NO_COMP
static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
+
static int zlib_inited = 0;
static void ossl_init_zlib(void)
{
/* Do nothing - we need to know about this for the later cleanup */
zlib_inited = 1;
}
+#endif
static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
{
if (locals == NULL)
return;
-#ifndef OPENSSL_NO_ASYNC
if (locals->async) {
#ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
#endif
ASYNC_cleanup_thread();
}
-#endif
if (locals->err_state) {
#ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
- "ERR_remove_thread_state(NULL)\n");
+ "ERR_remove_thread_state()\n");
#endif
- ERR_remove_thread_state(NULL);
+ ERR_remove_thread_state();
}
OPENSSL_free(locals);
OPENSSL_free(lasthandler);
}
stop_handlers = NULL;
+
+ CRYPTO_THREAD_lock_free(init_lock);
+
/*
* We assume we are single-threaded for this function, i.e. no race
* conditions for the various "*_inited" vars below.
*/
+#ifndef OPENSSL_NO_COMP
if (zlib_inited) {
#ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
- "COMP_zlib_cleanup()\n");
+ "comp_zlib_cleanup_internal()\n");
#endif
- COMP_zlib_cleanup();
+ comp_zlib_cleanup_internal();
}
+#endif
-#ifndef OPENSSL_NO_ASYNC
if (async_inited) {
# ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
# endif
async_deinit();
}
-#endif
-
-#ifndef OPENSSL_NO_ENGINE
- if (engine_inited) {
-# ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
- "ENGINE_cleanup()\n");
-# endif
- ENGINE_cleanup();
- }
-#endif
if (load_crypto_strings_inited) {
#ifdef OPENSSL_INIT_DEBUG
fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
- "ERR_free_strings()\n");
+ "err_free_strings_intern()\n");
#endif
- ERR_free_strings();
+ err_free_strings_intern();
}
CRYPTO_THREAD_cleanup_local(&threadstopkey);
#ifdef OPENSSL_INIT_DEBUG
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "CRYPTO_cleanup_all_ex_data()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "EVP_cleanup()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "rand_cleanup_intern()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
"CONF_modules_free()\n");
- fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
- "RAND_cleanup()\n");
+#ifndef OPENSSL_NO_ENGINE
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "ENGINE_cleanup()\n");
#endif
- CRYPTO_cleanup_all_ex_data();
- EVP_cleanup();
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "crypto_cleanup_all_ex_data_intern()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "BIO_sock_cleanup()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "EVP_cleanup()\n");
+ fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+ "OBJ_cleanup()\n");
+#endif
+ /*
+ * Note that cleanup order is important:
+ * - rand_cleanup_intern could call an ENINGE's RAND cleanup function so
+ * must be called before ENGINE_cleanup()
+ * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
+ * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
+ * - CONF_modules_free() can end up in ENGINE code so must be called before
+ * ENGINE_cleanup()
+ */
+ rand_cleanup_intern();
CONF_modules_free();
- RAND_cleanup();
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ crypto_cleanup_all_ex_data_intern();
+#ifndef OPENSSL_NO_SOCK
+ BIO_sock_cleanup();
+#endif
+ EVP_cleanup();
+ OBJ_cleanup();
base_inited = 0;
}
if (opts & OPENSSL_INIT_LOAD_CONFIG) {
int ret;
- CRYPTO_w_lock(CRYPTO_LOCK_INIT);
+ CRYPTO_THREAD_write_lock(init_lock);
config_filename = (settings == NULL) ? NULL : settings->config_name;
ret = CRYPTO_THREAD_run_once(&config, ossl_init_config);
- CRYPTO_w_unlock(CRYPTO_LOCK_INIT);
+ CRYPTO_THREAD_unlock(init_lock);
if (!ret)
return 0;
}
-#ifndef OPENSSL_NO_ASYNC
if ((opts & OPENSSL_INIT_ASYNC)
&& !CRYPTO_THREAD_run_once(&async, ossl_init_async))
return 0;
-#endif
+
#ifndef OPENSSL_NO_ENGINE
if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
&& !CRYPTO_THREAD_run_once(&engine_openssl,
# ifndef OPENSSL_NO_STATIC_ENGINE
# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
- && CRYPTO_THREAD_run_once(&engine_padlock,
- ossl_init_engine_padlock))
+ && !CRYPTO_THREAD_run_once(&engine_padlock,
+ ossl_init_engine_padlock))
return 0;
# endif
# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
if ((opts & OPENSSL_INIT_ENGINE_CAPI)
- && CRYPTO_THREAD_run_once(&engine_capi, ossl_init_engine_capi))
+ && !CRYPTO_THREAD_run_once(&engine_capi, ossl_init_engine_capi))
return 0;
# endif
if ((opts & OPENSSL_INIT_ENGINE_DASYNC)
}
#endif
+#ifndef OPENSSL_NO_COMP
if ((opts & OPENSSL_INIT_ZLIB)
- && CRYPTO_THREAD_run_once(&zlib, ossl_init_zlib))
+ && !CRYPTO_THREAD_run_once(&zlib, ossl_init_zlib))
return 0;
+#endif
return 1;
}
return 1;
}
-
-