Commit ca52fe62e7 for openssl.org
commit ca52fe62e7f3349f5c2a52583aef833eaff6e282
Author: Bob Beck <beck@openssl.org>
Date: Fri Jan 30 15:33:45 2026 -0700
Remove OPENSSL_atexit();
OSSLINAPPL (OpenSSL Is Not A Public Portability Layer)
I blame @nhorman and @sashan, who made me update the adjacent
documentation, and it was sitting there like an unloved and
ignored chronically ill pet with no hope for any future
quality of life.
Since this really does not need an alternative API or a
deprecation stragegy, we can simply remove it. Anyone
who was using this can use libc atexit() if they must.
Reviewed-by: Saša NedvÄ›dický <sashan@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
MergeDate: Wed Feb 11 17:37:33 2026
(Merged from https://github.com/openssl/openssl/pull/29874)
diff --git a/CHANGES.md b/CHANGES.md
index 217dda6591..c0fe9bac18 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -56,6 +56,10 @@ OpenSSL 4.0
*Shane Lontis*
+ * OPENSSL_atexit() was removed.
+
+ *Bob Beck*
+
* Support of deprecated elliptic curves in TLS according to RFC 8422 was
disabled at compile-time by default. To enable it, use the
`enable-tls-deprecated-ec` compilation option.
diff --git a/crypto/init.c b/crypto/init.c
index db9f18aee0..f865affda9 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -500,12 +500,3 @@ void OPENSSL_cleanup(void)
ossl_cleanup_destructor();
#endif /* defined(DO_NOT_SKIP_OPENSSL_CLEANUP) */
}
-
-int OPENSSL_atexit(void (*handler)(void))
-{
-#if defined(__TANDEM)
- return 0;
-#else
- return atexit(handler) == 0;
-#endif
-}
diff --git a/doc/man3/OPENSSL_init_crypto.pod b/doc/man3/OPENSSL_init_crypto.pod
index f79d1b97dc..733f5c665d 100644
--- a/doc/man3/OPENSSL_init_crypto.pod
+++ b/doc/man3/OPENSSL_init_crypto.pod
@@ -4,7 +4,7 @@
OPENSSL_INIT_new, OPENSSL_INIT_set_config_filename,
OPENSSL_INIT_set_config_appname, OPENSSL_INIT_set_config_file_flags,
-OPENSSL_INIT_free, OPENSSL_init_crypto, OPENSSL_cleanup, OPENSSL_atexit,
+OPENSSL_INIT_free, OPENSSL_init_crypto, OPENSSL_cleanup,
OPENSSL_thread_stop_ex, OPENSSL_thread_stop - OpenSSL initialisation
and deinitialisation functions
@@ -14,7 +14,6 @@ and deinitialisation functions
void OPENSSL_cleanup(void);
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
- int OPENSSL_atexit(void (*handler)(void));
void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx);
void OPENSSL_thread_stop(void);
@@ -165,8 +164,6 @@ OpenSSL error strings will not be available, only an error code. This code can
be put through the openssl errstr command line application to produce a human
readable error (see L<openssl-errstr(1)>).
-The OPENSSL_atexit() is a wrapper on atexit(3) provided by the platform's libc.
-
The OPENSSL_thread_stop_ex() function deallocates resources associated
with the current thread for the given OSSL_LIB_CTX B<ctx>. The B<ctx> parameter
can be NULL in which case the default OSSL_LIB_CTX is used.
@@ -229,7 +226,7 @@ call should use the RTLD_NODELETE flag (where available on the platform).
=head1 RETURN VALUES
-The functions OPENSSL_init_crypto, OPENSSL_atexit() and
+The functions OPENSSL_init_crypto, and
OPENSSL_INIT_set_config_appname() return 1 on success or 0 on error.
=head1 SEE ALSO
@@ -238,7 +235,7 @@ L<OPENSSL_init_ssl(3)>
=head1 HISTORY
-The OPENSSL_init_crypto(), OPENSSL_cleanup(), OPENSSL_atexit(),
+The OPENSSL_init_crypto(), OPENSSL_cleanup()
OPENSSL_thread_stop(), OPENSSL_INIT_new(), OPENSSL_INIT_set_config_appname()
and OPENSSL_INIT_free() functions were added in OpenSSL 1.1.0.
diff --git a/doc/man7/ossl-removed-api.pod b/doc/man7/ossl-removed-api.pod
index 05dadb8988..a0327c2fe2 100644
--- a/doc/man7/ossl-removed-api.pod
+++ b/doc/man7/ossl-removed-api.pod
@@ -391,6 +391,8 @@ This includes consulting the L<ossl-guide-migration(7)> documentation.
=item EVP_PKEY_asn1_set_security_bits (Deprecated in 3.6.0) - consult L<ossl-guide-migration(7)>
+=item OPENSSL_atexit - No longer used, use libc atexit() if you must use this.
+
=back
=head1 SEE ALSO
diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in
index c9dc3706f3..c111cd2bc5 100644
--- a/include/openssl/crypto.h.in
+++ b/include/openssl/crypto.h.in
@@ -516,7 +516,6 @@ int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len);
/* Library initialisation functions */
void OPENSSL_cleanup(void);
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
-int OPENSSL_atexit(void (*handler)(void));
void OPENSSL_thread_stop(void);
void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx);
diff --git a/test/shlibloadtest.c b/test/shlibloadtest.c
index 5fa37415a5..d1b8628877 100644
--- a/test/shlibloadtest.c
+++ b/test/shlibloadtest.c
@@ -21,7 +21,6 @@ typedef const SSL_METHOD *(*TLS_method_t)(void);
typedef SSL_CTX *(*SSL_CTX_new_t)(const SSL_METHOD *meth);
typedef void (*SSL_CTX_free_t)(SSL_CTX *);
typedef int (*OPENSSL_init_crypto_t)(uint64_t, void *);
-typedef int (*OPENSSL_atexit_t)(void (*handler)(void));
typedef unsigned long (*ERR_get_error_t)(void);
typedef unsigned long (*OPENSSL_version_major_t)(void);
typedef unsigned long (*OPENSSL_version_minor_t)(void);
@@ -73,7 +72,6 @@ static int test_lib(void)
OPENSSL_version_major_t myOPENSSL_version_major;
OPENSSL_version_minor_t myOPENSSL_version_minor;
OPENSSL_version_patch_t myOPENSSL_version_patch;
- OPENSSL_atexit_t myOPENSSL_atexit;
int result = 0;
switch (test_type) {
@@ -124,8 +122,7 @@ static int test_lib(void)
if (!sd_sym(cryptolib, "ERR_get_error", &symbols[0].sym)
|| !sd_sym(cryptolib, "OPENSSL_version_major", &symbols[1].sym)
|| !sd_sym(cryptolib, "OPENSSL_version_minor", &symbols[2].sym)
- || !sd_sym(cryptolib, "OPENSSL_version_patch", &symbols[3].sym)
- || !sd_sym(cryptolib, "OPENSSL_atexit", &symbols[4].sym)) {
+ || !sd_sym(cryptolib, "OPENSSL_version_patch", &symbols[3].sym)) {
fprintf(stderr, "Failed to load libcrypto symbols\n");
goto end;
}
@@ -146,8 +143,7 @@ static int test_lib(void)
goto end;
}
- myOPENSSL_atexit = (OPENSSL_atexit_t)symbols[4].func;
- if (!myOPENSSL_atexit(atexit_handler)) {
+ if (atexit(atexit_handler) != 0) {
fprintf(stderr, "Failed to register atexit handler\n");
goto end;
}
@@ -159,7 +155,7 @@ static int test_lib(void)
/*
* This is resembling the code used in ossl_init_base() and
- * OPENSSL_atexit() to block unloading the library after dlclose().
+ * atexit() to block unloading the library after dlclose().
* We are not testing this on Windows, because it is done there in a
* completely different way. Especially as a call to DSO_dsobyaddr()
* will always return an error, because DSO_pathbyaddr() is not
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 275f01301e..80eb4309a7 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -3601,7 +3601,6 @@ OPENSSL_gmtime_diff ? 4_0_0 EXIST::FUNCTION:
CRYPTO_memcmp ? 4_0_0 EXIST::FUNCTION:
OPENSSL_cleanup ? 4_0_0 EXIST::FUNCTION:
OPENSSL_init_crypto ? 4_0_0 EXIST::FUNCTION:
-OPENSSL_atexit ? 4_0_0 EXIST::FUNCTION:
OPENSSL_thread_stop ? 4_0_0 EXIST::FUNCTION:
OPENSSL_thread_stop_ex ? 4_0_0 EXIST::FUNCTION:
OPENSSL_INIT_new ? 4_0_0 EXIST::FUNCTION: