]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Implement OPENSSL_INIT_NO_ATEXIT
authorMatt Caswell <matt@openssl.org>
Thu, 15 Nov 2018 16:27:34 +0000 (16:27 +0000)
committerMatt Caswell <matt@openssl.org>
Fri, 4 Jan 2019 13:19:39 +0000 (13:19 +0000)
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7647)

crypto/init.c
doc/man3/OPENSSL_init_crypto.pod
include/openssl/crypto.h

index 86419d022ef58681e975e4d3e60e2db235b21630..321ac11cf412f629a4acffed4067dddd157eac58 100644 (file)
@@ -100,10 +100,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base)
         return 0;
     if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
         goto err;
-#ifndef OPENSSL_SYS_UEFI
-    if (atexit(OPENSSL_cleanup) != 0)
-        goto err;
-#endif
     OPENSSL_cpuid_setup();
 
     destructor_key.value = key;
@@ -121,6 +117,30 @@ err:
     return 0;
 }
 
+static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
+{
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
+# endif
+#ifndef OPENSSL_SYS_UEFI
+    if (atexit(OPENSSL_cleanup) != 0)
+        return 0;
+#endif
+
+    return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
+                           ossl_init_register_atexit)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
+#endif
+    /* Do nothing in this case */
+    return 1;
+}
+
 static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
 {
@@ -621,6 +641,14 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
     if (!RUN_ONCE(&base, ossl_init_base))
         return 0;
 
+    if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) {
+        if (!RUN_ONCE_ALT(&register_atexit, ossl_init_no_register_atexit,
+                          ossl_init_register_atexit))
+            return 0;
+    } else if (!RUN_ONCE(&register_atexit, ossl_init_register_atexit)) {
+        return 0;
+    }
+
     if (!(opts & OPENSSL_INIT_BASE_ONLY)
             && !RUN_ONCE(&load_crypto_nodelete,
                          ossl_init_load_crypto_nodelete))
index ea6b00dc633e45054422a71b331369f883ca9101..575d0f1a2c368aa0fd5c67d1a2c8465bb43385d9 100644 (file)
@@ -33,7 +33,7 @@ As of version 1.1.0 OpenSSL will automatically allocate all resources that it
 needs so no explicit initialisation is required. Similarly it will also
 automatically deinitialise as required.
 
-However, there way be situations when explicit initialisation is desirable or
+However, there may be situations when explicit initialisation is desirable or
 needed, for example when some non-default initialisation is required. The
 function OPENSSL_init_crypto() can be used for this purpose for
 libcrypto (see also L<OPENSSL_init_ssl(3)> for the libssl
@@ -157,6 +157,13 @@ engines. This not a default option.
 With this option the library will register its fork handlers.
 See OPENSSL_fork_prepare(3) for details.
 
+=item OPENSSL_INIT_NO_ATEXIT
+
+By default OpenSSL will attempt to clean itself up when the process exits via an
+"atexit" handler. Using this option suppresses that behaviour. This means that
+the application will have to clean up OpenSSL explicitly using
+OPENSSL_cleanup().
+
 =back
 
 Multiple options may be combined together in a single call to
index fc8f32bdc2db21d957604cb5e7735f3a7bca7d9a..4b34812b2457dd149d043c2de900368fe13a37a9 100644 (file)
@@ -379,7 +379,7 @@ int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len);
 /* OPENSSL_INIT_ZLIB                         0x00010000L */
 # define OPENSSL_INIT_ATFORK                 0x00020000L
 /* OPENSSL_INIT_BASE_ONLY                    0x00040000L */
-/* FREE: 0x00080000L */
+# define OPENSSL_INIT_NO_ATEXIT              0x00080000L
 /* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */
 # define OPENSSL_INIT_NO_ADD_ALL_MACS        0x04000000L
 # define OPENSSL_INIT_ADD_ALL_MACS           0x08000000L