summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2023-09-25 16:44:47 +0100
committerPauli <pauli@openssl.org>2023-10-03 18:54:03 +1100
commit6b3f7f0b28afc3e25ce505e5fde2d9f2b50cdb9e (patch)
tree5436342c0d94876eb85a340b1477ae4468fb05b2 /crypto
parent354053395fbd20e5efb584427b5da9be9231fd93 (diff)
Fix a mem leak when the FIPS provider is used in a different thread
We were neglecting to register the main thread to receive thread stop notifications. This is important if the thread that starts the FIPS provider is not the same one that is used when OPENSSL_cleanup() is called. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/22210)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/initthread.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/crypto/initthread.c b/crypto/initthread.c
index 54a33c3286..23ad0a0739 100644
--- a/crypto/initthread.c
+++ b/crypto/initthread.c
@@ -249,6 +249,15 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
#else
+static void ossl_arg_thread_stop(void *arg);
+
+/* Register the current thread so that we are informed if it gets stopped */
+int ossl_thread_register_fips(OSSL_LIB_CTX *libctx)
+{
+ return c_thread_start(FIPS_get_core_handle(libctx), ossl_arg_thread_stop,
+ libctx);
+}
+
void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
{
THREAD_EVENT_HANDLER **hands = NULL;
@@ -268,6 +277,16 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
if (!CRYPTO_THREAD_set_local(tlocal, hands))
goto err;
+ /*
+ * We should ideally call ossl_thread_register_fips() here. This function
+ * is called during the startup of the FIPS provider and we need to ensure
+ * that the main thread is registered to receive thread callbacks in order
+ * to free |hands| that we allocated above. However we are too early in
+ * the FIPS provider initialisation that FIPS_get_core_handle() doesn't work
+ * yet. So we defer this to the main provider OSSL_provider_init_int()
+ * function.
+ */
+
return tlocal;
err:
OPENSSL_free(hands);
@@ -379,8 +398,7 @@ int ossl_init_thread_start(const void *index, void *arg,
* libcrypto to tell us about later thread stop events. c_thread_start
* is a callback to libcrypto defined in fipsprov.c
*/
- if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop,
- ctx))
+ if (!ossl_thread_register_fips(ctx))
return 0;
}
#endif