ED25519 public key method.
[openssl.git] / crypto / init.c
index e457b2dd0e89517649a319f65ac7e36c69908952..265d54d807290cd114bfe071e85f3ba97f169a76 100644 (file)
@@ -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,6 +82,13 @@ 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;
 
 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
@@ -97,13 +107,15 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base)
 # 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
@@ -503,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)
@@ -638,8 +650,10 @@ int OPENSSL_atexit(void (*handler)(void))
         {
             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
     }