]> git.feebdaed.xyz Git - 0xmirror/openssl.git/commitdiff
Update NEWS.md
authorSashan <anedvedicky@gmail.com>
Mon, 15 Dec 2025 15:33:35 +0000 (16:33 +0100)
committerNeil Horman <nhorman@openssl.org>
Fri, 19 Dec 2025 17:06:38 +0000 (12:06 -0500)
Co-authored-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29385)

15 files changed:
NEWS.md
apps/fipsinstall.c
crypto/init.c
crypto/initthread.c
crypto/s390x_arch.h
crypto/s390xcap.c
doc/man3/OPENSSL_init_crypto.pod
doc/man7/ossl-guide-migration.pod
include/openssl/crypto.h.in
providers/implementations/rands/seeding/rand_unix.c
ssl/rio/rio_notifier.c
test/defltfips_test.c
test/endecode_test.c
test/rand_test.c
test/testutil/main.c

diff --git a/NEWS.md b/NEWS.md
index e95e94ed2cacb305f5e7112b39243920134a6469..f966d8cfda500ecdece8992841d6ca4d09924225 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -29,7 +29,7 @@ OpenSSL 4.0
 
   * The script tool `c_rehash` was removed. Use `openssl rehash` instead.
 
-  * OPENSSL_cleanup() no longer invoked as atexit(3) handler by default.
+  * libcrypto no longer cleans up globally allocated data via atexit()
 
   * ENGINE support was removed. The `no-engine` build option and the
    `OPENSSL_NO_ENGINE` macro is always present.
index 10114cb1d836d0da341972e4ac836b4b125eaf14..ea54a00cffc107bc710fb708b3defa0f63a9794b 100644 (file)
@@ -967,7 +967,6 @@ cleanup:
     EVP_MAC_CTX_free(ctx);
     OPENSSL_free(read_buffer);
     free_config_and_unload(conf);
-    OPENSSL_cleanup();
     return ret;
 }
 
index 2aeffb96e5eabbed5ef59ace43160508242db489..dd866d7e085c1701ad6cde12ed2f3b7b541bd85f 100644 (file)
 #include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
 #include <openssl/trace.h>
 #include <openssl/ssl.h> /* for OPENSSL_INIT_(NO_)?LOAD_SSL_STRINGS */
+#include "crypto/bn.h"
 #include "crypto/ctype.h"
 #include "sslerr.h"
 
+#ifdef S390X_MOD_EXP
+#include "s390x_arch.h"
+#endif
+
 static int stopped = 0;
 static uint64_t optsdone = 0;
 
@@ -77,58 +82,6 @@ err:
     return 0;
 }
 
-static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
-{
-    OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n");
-
-#if !defined(OPENSSL_USE_NODELETE) \
-    && !defined(OPENSSL_NO_PINSHARED)
-#if defined(DSO_WIN32) && !defined(_WIN32_WCE)
-    {
-        HMODULE handle = NULL;
-        BOOL ret;
-
-        /* We don't use the DSO route for WIN32 because there is a better way */
-        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
-                | GET_MODULE_HANDLE_EX_FLAG_PIN,
-            (void *)&base_inited, &handle);
-
-        OSSL_TRACE1(INIT,
-            "ossl_init_load_crypto_nodelete: "
-            "obtained DSO reference? %s\n",
-            (ret == TRUE ? "No!" : "Yes."));
-        return (ret == TRUE) ? 1 : 0;
-    }
-#elif !defined(DSO_NONE)
-    /*
-     * Deliberately leak a reference to ourselves. This will force the library
-     * to remain loaded until the OPENSSL_cleanup()  is called.
-     */
-    {
-        DSO *dso;
-        void *err;
-
-        if (!err_shelve_state(&err))
-            return 0;
-
-        dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
-        /*
-         * In case of No!, it is uncertain our exit()-handlers can still be
-         * called. After dlclose() the whole library might have been unloaded
-         * already.
-         */
-        OSSL_TRACE1(INIT, "obtained DSO reference? %s\n",
-            (dso == NULL ? "No!" : "Yes."));
-        DSO_free(dso);
-        err_unshelve_state(err);
-    }
-#endif
-#endif
-
-    return 1;
-}
-
 static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
 
 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
@@ -270,7 +223,7 @@ void OPENSSL_cleanup(void)
     if (!base_inited)
         return;
 
-    /* Might be explicitly called a*/
+    /* Might be explicitly called */
     if (stopped)
         return;
     stopped = 1;
@@ -357,6 +310,10 @@ void OPENSSL_cleanup(void)
     OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
     ossl_trace_cleanup();
 
+#ifdef S390X_MOD_EXP
+    OPENSSL_s390x_cleanup();
+#endif
+
     base_inited = 0;
 }
 
@@ -402,10 +359,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
      *
      * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
      * *only* option specified.  With that option we return immediately after
-     * doing the requested limited initialization.  Note that
-     * err_shelve_state() called by us via ossl_init_load_crypto_nodelete()
-     * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with
-     * base already initialized this is a harmless NOOP.
+     * doing the requested limited initialization.
      *
      * If we remain the only caller of err_shelve_state() the recursion should
      * perhaps be removed, but if in doubt, it can be left in place.
@@ -428,9 +382,6 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
             return 1;
     }
 
-    if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
-        return 0;
-
     if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
         && !RUN_ONCE_ALT(&load_crypto_strings,
             ossl_init_no_load_crypto_strings,
index d408ea9ca16d2c69dc72106fdf43e9c18ed91b27..1e1b9e69db540e1dbc156e869179b88e66c91888 100644 (file)
@@ -326,12 +326,7 @@ err:
 
 void ossl_thread_event_ctx_free(OSSL_LIB_CTX *ctx)
 {
-    THREAD_EVENT_HANDLER **hands;
-
-    hands = (THREAD_EVENT_HANDLER **)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx);
     CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, NULL);
-
-    OPENSSL_free(hands);
 }
 
 static void ossl_arg_thread_stop(void *arg)
index c3a805b3594a421ecd904c0fb4175ea03634f016..f5ff696dcdfca1e7f5fd653f09cb90716dcc1bbe 100644 (file)
@@ -31,6 +31,7 @@ void s390x_kma(const unsigned char *aad, size_t alen, const unsigned char *in,
 int s390x_pcc(unsigned int fc, void *param);
 int s390x_kdsa(unsigned int fc, void *param, const unsigned char *in,
     size_t len);
+void OPENSSL_s390x_cleanup(void);
 
 void s390x_flip_endian32(unsigned char dst[32], const unsigned char src[32]);
 void s390x_flip_endian64(unsigned char dst[64], const unsigned char src[64]);
index e1e75173afe5f1896b2e9cf836495b29d3fd59cb..77b3b0307a6cf8efd2d545b5763a6248d177f05f 100644 (file)
@@ -221,7 +221,6 @@ void OPENSSL_cpuid_setup(void)
         OPENSSL_s390xcex = -1;
     } else {
         OPENSSL_s390xcex = open("/dev/z90crypt", O_RDWR | O_CLOEXEC);
-        OPENSSL_atexit(OPENSSL_s390x_cleanup);
     }
     OPENSSL_s390xcex_nodev = 0;
 #endif
index 0740c219d2d62f0fcc87e2dd84bda7b419a2375c..6d9628054d9fb194b8d6356ef0b764c89d3d0ccd 100644 (file)
@@ -124,6 +124,10 @@ sub-library (see L<ASYNC_start_job(3)>). This is 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
+
+The option has no effect in 4.0 and later.
+
 =back
 
 Multiple options may be combined together in a single call to
index 4ce7b6ec8f6aa9b2a923fb98298ba58850af563b..64284c9091cdf3620dc93109cb40a728c655945c 100644 (file)
@@ -37,6 +37,11 @@ features available in OpenSSL 4.0.
 Some functions have been removed that were deprecated in previous
 versions of OpenSSL. See L<ossl-removed-api(7)>.
 
+libcrypto no longer arms OPENSSL_cleanup() function as atexit(3) handler.
+Memory leak detectors may report there is allocated, but still reachable,
+allocated memory at application exit. If clean report is desired, then
+application must call OPENSSL_cleanup() explicitly before main() returns.
+
 =head1 OPENSSL 3.6
 
 =head2 Main Changes from OpenSSL 3.5
index 9341985026504e0129cdf29a8547b272c0c8c725..c9dc3706f373b6d7f584d5487cf757eb256e5acc 100644 (file)
@@ -490,8 +490,8 @@ int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len);
 /* FREE:                                     0x00010000L */
 #define OPENSSL_INIT_ATFORK 0x00020000L
 /* OPENSSL_INIT_BASE_ONLY                    0x00040000L */
+#define OPENSSL_INIT_NO_ATEXIT 0x00080000L
 /* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */
-/* FREE: 0x00080000L */
 /* FREE: 0x04000000L */
 /* FREE: 0x08000000L */
 /* FREE: 0x10000000L */
index 47643d3c671f2ddbd15e83b166894ccbe2901e22..1af996b25fefe84f3323c0bedc8e3a6a6243b9ae 100644 (file)
@@ -422,11 +422,6 @@ static int keep_random_devices_open = 1;
     && defined(OPENSSL_RAND_SEED_GETRANDOM)
 static void *shm_addr;
 
-static void cleanup_shm(void)
-{
-    shmdt(shm_addr);
-}
-
 /*
  * Ensure that the system randomness source has been adequately seeded.
  * This is done by having the first start of libcrypto, wait until the device
@@ -493,8 +488,8 @@ static int wait_random_seeded(void)
              * If this call fails, it isn't a big problem.
              */
             shm_addr = shmat(shm_id, NULL, SHM_RDONLY);
-            if (shm_addr != (void *)-1)
-                OPENSSL_atexit(&cleanup_shm);
+            if (shm_addr == (void *)-1)
+                shm_addr = NULL;
         }
     }
     return seeded;
@@ -583,6 +578,14 @@ void ossl_rand_pool_cleanup(void)
 
     for (i = 0; i < OSSL_NELEM(random_devices); i++)
         close_random_device(i);
+
+#if defined(__linux) && defined(DEVRANDOM_WAIT) \
+    && defined(OPENSSL_RAND_SEED_GETRANDOM)
+    if (shm_addr != NULL) {
+        shmdt(shm_addr);
+        shm_addr = NULL;
+    }
+#endif
 }
 
 void ossl_rand_pool_keep_random_devices_open(int keep)
index ea40790d627bd36f5c294e30ac16abd69b6ee0ca..0d84880065d42a21870972f2120c4c77824065b0 100644 (file)
@@ -29,7 +29,9 @@ static int set_cloexec(int fd)
 #if defined(OPENSSL_SYS_WINDOWS)
 
 static CRYPTO_ONCE ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *wsa_lock;
 static int wsa_started;
+static int wsa_ref;
 
 static void ossl_wsa_cleanup(void)
 {
@@ -37,6 +39,9 @@ static void ossl_wsa_cleanup(void)
         wsa_started = 0;
         WSACleanup();
     }
+
+    CRYPTO_THREAD_lock_free(wsa_lock);
+    wsa_lock = NULL;
 }
 
 DEFINE_RUN_ONCE_STATIC(do_wsa_startup)
@@ -44,16 +49,43 @@ DEFINE_RUN_ONCE_STATIC(do_wsa_startup)
     WORD versionreq = 0x0202; /* Version 2.2 */
     WSADATA wsadata;
 
-    if (WSAStartup(versionreq, &wsadata) != 0)
+    wsa_lock = CRYPTO_THREAD_lock_new();
+    if (wsa_lock == NULL)
+        return 0;
+
+    if (WSAStartup(versionreq, &wsadata) != 0) {
+        CRYPTO_THREAD_lock_free(wsa_lock);
+        wsa_lock = NULL;
         return 0;
+    }
     wsa_started = 1;
-    OPENSSL_atexit(ossl_wsa_cleanup);
+
     return 1;
 }
 
 static ossl_inline int ensure_wsa_startup(void)
 {
-    return RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+    int rv, unused;
+
+    rv = RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+    if (rv != 0)
+        CRYPTO_atomic_add(&wsa_ref, 1, &unused, wsa_lock);
+
+    return rv;
+}
+
+static void wsa_done(void)
+{
+    int ref;
+
+    if (wsa_lock != NULL) {
+        CRYPTO_atomic_add(&wsa_ref, -1, &ref, wsa_lock);
+        if (ref == 0) {
+            ossl_wsa_cleanup();
+            ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+            wsa_lock = NULL;
+        }
+    }
 }
 
 #endif
@@ -154,6 +186,8 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
     if (!ensure_wsa_startup()) {
         ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
             "Cannot start Windows sockets");
+
+        wsa_done();
         return 0;
     }
 #endif
@@ -340,6 +374,9 @@ void ossl_rio_notifier_cleanup(RIO_NOTIFIER *nfy)
     BIO_closesocket(nfy->wfd);
     BIO_closesocket(nfy->rfd);
     nfy->rfd = nfy->wfd = -1;
+#if defined(OPENSSL_SYS_WINDOWS)
+    wsa_done();
+#endif
 }
 
 int ossl_rio_notifier_signal(RIO_NOTIFIER *nfy)
index b7e85211c4e1e16806072e9d1d414877c1d2475d..16d834b020c0948e0c6ccd68ed982447dd826b54 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 #include <string.h>
-#include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/provider.h>
 #include "testutil.h"
@@ -69,11 +68,6 @@ static int test_is_fips_enabled(void)
     return 1;
 }
 
-void cleanup_tests(void)
-{
-    OPENSSL_cleanup();
-}
-
 int setup_tests(void)
 {
     size_t argc;
index 58fd12473b54c9be4107bf7b117263fea1a7364c..6081ef5d0bef93f43f8c354efa350d311a04dcd4 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <string.h>
 #include <openssl/core_dispatch.h>
-#include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/rsa.h>
@@ -1768,6 +1767,4 @@ void cleanup_tests(void)
     OSSL_PROVIDER_unload(keyprov);
     OSSL_LIB_CTX_free(testctx);
     OSSL_LIB_CTX_free(keyctx);
-
-    OPENSSL_cleanup();
 }
index 0ac097cb34a1e4215b6ca3f16b456c22e2fd0ea5..0fbd89542f28ac6a3d33cb2e40a129e0ddb0a11c 100644 (file)
@@ -7,7 +7,6 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/crypto.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/bio.h>
@@ -276,11 +275,6 @@ err:
     return res;
 }
 
-void cleanup_tests(void)
-{
-    OPENSSL_cleanup();
-}
-
 int setup_tests(void)
 {
     if (!test_skip_common_options()) {
index 468d18a82524d7f28aaa7c216607cde2410e978a..2d7c88c3831bae08b71fed8e69d41fcb5e5a67a8 100644 (file)
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <openssl/crypto.h>
 #include "../testutil.h"
 #include "output.h"
 #include "tu_local.h"
@@ -39,5 +40,6 @@ int main(int argc, char *argv[])
 end:
     ret = pulldown_test_framework(ret);
     test_close_streams();
+    OPENSSL_cleanup();
     return ret;
 }