From c2b3db245452f185948b4f767f7e1051b6bd59a7 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Thu, 15 Nov 2018 16:27:34 +0000 Subject: [PATCH] Implement OPENSSL_INIT_NO_ATEXIT Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/7983) --- crypto/init.c | 36 ++++++++++++++++++++++++++++---- doc/man3/OPENSSL_init_crypto.pod | 9 +++++++- include/openssl/crypto.h | 1 + 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/crypto/init.c b/crypto/init.c index f20a12f069..1bafb17a92 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -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) { @@ -598,6 +618,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(®ister_atexit, ossl_init_no_register_atexit, + ossl_init_register_atexit)) + return 0; + } else if (!RUN_ONCE(®ister_atexit, ossl_init_register_atexit)) { + return 0; + } + if (!(opts & OPENSSL_INIT_BASE_ONLY) && !RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete)) diff --git a/doc/man3/OPENSSL_init_crypto.pod b/doc/man3/OPENSSL_init_crypto.pod index a259539f05..b53ab6bd10 100644 --- a/doc/man3/OPENSSL_init_crypto.pod +++ b/doc/man3/OPENSSL_init_crypto.pod @@ -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 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 diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 7e50b1bf46..d23d9b3156 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -377,6 +377,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 */ +# define OPENSSL_INIT_NO_ATEXIT 0x00080000L /* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */ /* Max OPENSSL_INIT flag value is 0x80000000 */ -- 2.25.1