From: Matt Caswell Date: Thu, 15 Nov 2018 16:27:34 +0000 (+0000) Subject: Implement OPENSSL_INIT_NO_ATEXIT X-Git-Tag: openssl-3.0.0-alpha1~2666 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=8f6a5c56c17aa89b80fef73875beec53aef1f2c8 Implement OPENSSL_INIT_NO_ATEXIT Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/7647) --- diff --git a/crypto/init.c b/crypto/init.c index 86419d022e..321ac11cf4 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) { @@ -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(®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 ea6b00dc63..575d0f1a2c 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 fc8f32bdc2..4b34812b24 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -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