X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Finit.c;h=265d54d807290cd114bfe071e85f3ba97f169a76;hp=cfa0ce0c865d6c3d6fd0ddf08d45f3b3e7375f17;hb=42a3008aa406429394ff2ae03114d0ac47214e0a;hpb=b6d5ba1a9f004d637acac18ae3519fe063b6b5e1 diff --git a/crypto/init.c b/crypto/init.c index cfa0ce0c86..265d54d807 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -67,6 +67,9 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base) { #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n"); +#endif +#ifndef OPENSSL_NO_CRYPTO_MDEBUG + ossl_malloc_setup_failures(); #endif /* * We use a dummy thread local key here. We use the destructor to detect @@ -79,19 +82,42 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base) if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) return 0; OPENSSL_cpuid_setup(); + + /* + * BIG FAT WARNING! + * Everything needed to be initialized in this function before threads + * come along MUST happen before base_inited is set to 1, or we will + * see race conditions. + */ base_inited = 1; -#ifndef OPENSSL_USE_NODELETE +#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) +# ifdef DSO_WIN32 + { + HMODULE handle = NULL; + BOOL ret; + + /* We don't use the DSO route for WIN32 because there is a better way */ + ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + | GET_MODULE_HANDLE_EX_FLAG_PIN, + (void *)&base_inited, &handle); + + return (ret == TRUE) ? 1 : 0; + } +# else /* * Deliberately leak a reference to ourselves. This will force the library - * to remain loaded until the atexit() handler is run a process exit. + * to remain loaded until the atexit() handler is run at process exit. */ { DSO *dso = NULL; + ERR_set_mark(); dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); DSO_free(dso); + ERR_pop_to_mark(); } +# endif #endif return 1; @@ -489,7 +515,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) return 0; } - if (!RUN_ONCE(&base, ossl_init_base)) + if (!base_inited && !RUN_ONCE(&base, ossl_init_base)) return 0; if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) @@ -590,23 +616,46 @@ int OPENSSL_atexit(void (*handler)(void)) { OPENSSL_INIT_STOP *newhand; -#ifndef OPENSSL_USE_NODELETE - /* - * Deliberately leak a reference to the handler. This will force the - * library/code containing the handler to remain loaded until we run the - * atexit handler. If -znodelete has been used then this is unneccessary. - */ +#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) { - DSO *dso = NULL; union { void *sym; void (*func)(void); } handlersym; handlersym.func = handler; +# ifdef DSO_WIN32 + { + HMODULE handle = NULL; + BOOL ret; - dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); - DSO_free(dso); + /* + * We don't use the DSO route for WIN32 because there is a better + * way + */ + ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS + | GET_MODULE_HANDLE_EX_FLAG_PIN, + handlersym.sym, &handle); + + if (!ret) + return 0; + } +# else + /* + * Deliberately leak a reference to the handler. This will force the + * library/code containing the handler to remain loaded until we run the + * atexit handler. If -znodelete has been used then this is + * unneccessary. + */ + { + DSO *dso = NULL; + + ERR_set_mark(); + dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); + DSO_free(dso); + ERR_pop_to_mark(); + } +# endif } #endif