diff options
-rw-r--r-- | crypto/initthread.c | 22 | ||||
-rw-r--r-- | include/crypto/context.h | 1 | ||||
-rw-r--r-- | providers/fips/fipsprov.c | 9 |
3 files changed, 30 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 diff --git a/include/crypto/context.h b/include/crypto/context.h index 56c68f4ec1..af81e15e1d 100644 --- a/include/crypto/context.h +++ b/include/crypto/context.h @@ -21,6 +21,7 @@ void *ossl_child_prov_ctx_new(OSSL_LIB_CTX *); void *ossl_prov_drbg_nonce_ctx_new(OSSL_LIB_CTX *); void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *); void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *); +int ossl_thread_register_fips(OSSL_LIB_CTX *); void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *); void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *); #if defined(OPENSSL_THREADS) diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 607ee11763..7ec409710b 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -706,6 +706,15 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, fgbl->handle = handle; /* + * We need to register this thread to receive thread lifecycle callbacks. + * This wouldn't matter if the current thread is also the same thread that + * closes the FIPS provider down. But if that happens on a different thread + * then memory leaks could otherwise occur. + */ + if (!ossl_thread_register_fips(libctx)) + goto err; + + /* * We did initial set up of selftest_params in a local copy, because we * could not create fgbl until c_CRYPTO_zalloc was defined in the loop * above. |