]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add atexit configuration option to using atexit() in libcrypto at build-time.
authorRandall S. Becker <randall.becker@nexbridge.ca>
Thu, 25 Jan 2024 22:11:27 +0000 (22:11 +0000)
committerTomas Mraz <tomas@openssl.org>
Thu, 22 Feb 2024 09:35:32 +0000 (10:35 +0100)
This fixes an issue with a mix of atexit() usage in DLL and statically linked
libcrypto that came out in the test suite on NonStop, which has slightly
different DLL unload processing semantics compared to Linux. The change
allows a build configuration to select whether to register OPENSSL_cleanup()
with atexit() or not, so avoid situations where atexit() registration causes
SIGSEGV.

INSTALL.md and CHANGES.md have been modified to include and describe this
option.

Signed-off-by: Randall S. Becker <randall.becker@nexbridge.ca>
Signed-off-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23642)

.github/workflows/run-checker-ci.yml
CHANGES.md
Configure
INSTALL.md
NOTES-NONSTOP.md
crypto/init.c
test/recipes/90-test_shlibload.t

index 2ef91e802965ad25a69298075db01d1fe67e77c2..7d9b0ac73bb8dfc7b2fa1c29c86f9472010aa117 100644 (file)
@@ -17,6 +17,7 @@ jobs:
       fail-fast: false
       matrix:
         opt: [
+          no-atexit,
           no-cmp,
           no-cms,
           no-dgram,
index 6715426276065b748bd871049e8df62a096f5b90..027fd24ab59ea0e0a8a53dc0dac3ab96f4541b17 100644 (file)
@@ -27,6 +27,12 @@ OpenSSL 3.2
 
 ### Changes between 3.2.1 and 3.2.2 [xx XXX xxxx]
 
+ * New atexit configuration switch, which controls whether the OPENSSL_cleanup
+   is registered when libcrypto is unloaded. This can be used on platforms
+   where using atexit() from shared libraries causes crashes on exit.
+
+   *Randall S. Becker*
+
  * Fixed bug where SSL_export_keying_material() could not be used with QUIC
    connections. (#23560)
 
index caa69b4f476fb36ec34a8d552c0b5a97f5866256..c563373ea7f1efed422ef07a51d3569224d042cb 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -414,6 +414,7 @@ my @disablables = (
     "asan",
     "asm",
     "async",
+    "atexit",
     "autoalginit",
     "autoerrinit",
     "autoload-config",
index 37b57027f4f123ddd06311f469f8edd988b688c2..f7f92d8feb75989c65c85606767b24528a0940c9 100644 (file)
@@ -600,6 +600,13 @@ be used even with this option.
 
 Do not build support for async operations.
 
+### no-atexit
+
+Do not use `atexit()` in libcrypto builds.
+
+`atexit()` has varied semantics between platforms and can cause SIGSEGV in some
+circumstances. This options disables the atexit registration of OPENSSL_cleanup.
+
 ### no-autoalginit
 
 Don't automatically load all supported ciphers and digests.
index 65bfc1087dcabfaf6f941f68c513af0b810c1859..875a7d314aff99344aecb0c7db29524e63bf3eba 100644 (file)
@@ -57,7 +57,10 @@ relating to `atexit()` processing when a shared library is unloaded and when
 the program terminates. This limitation applies to all OpenSSL shared library
 components.
 
-A resolution to this situation is under investigation.
+It is possible to configure the build with `no-atexit` to avoid the SIGSEGV.
+Preferably, you can explicitly call `OPENSSL_cleanup()` from your application.
+It is not mandatory as it just deallocates various global data structures
+OpenSSL allocated.
 
 About Prefix and OpenSSLDir
 ---------------------------
index 33c739c30e6c78292793b19bbce781fe5e31dbee..40be312b8a6fd0a943a02c97b0caf352d5a73897 100644 (file)
@@ -97,17 +97,19 @@ static int win32atexit(void)
 
 DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
 {
-#ifdef OPENSSL_INIT_DEBUG
+#ifndef OPENSSL_NO_ATEXIT
+# ifdef OPENSSL_INIT_DEBUG
     fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
-#endif
-#ifndef OPENSSL_SYS_UEFI
-# if defined(_WIN32) && !defined(__BORLANDC__)
+# endif
+# ifndef OPENSSL_SYS_UEFI
+#  if defined(_WIN32) && !defined(__BORLANDC__)
     /* We use _onexit() in preference because it gets called on DLL unload */
     if (_onexit(win32atexit) == NULL)
         return 0;
-# else
+#  else
     if (atexit(OPENSSL_cleanup) != 0)
         return 0;
+#  endif
 # endif
 #endif
 
index 8f691dee38e8238c2844a41a5c9fa7ffaaa12847..af6bae20af341483eefd2bf9c1d4981e7f9c601c 100644 (file)
@@ -23,6 +23,7 @@ plan skip_all => "Test is disabled on AIX" if config('target') =~ m|^aix|;
 plan skip_all => "Test is disabled on NonStop" if config('target') =~ m|^nonstop|;
 plan skip_all => "Test only supported in a dso build" if disabled("dso");
 plan skip_all => "Test is disabled in an address sanitizer build" unless disabled("asan");
+plan skip_all => "Test is disabled if no-atexit is specified" if disabled("atexit");
 
 plan tests => 10;