diff options
Diffstat (limited to 'crypto/initthread.c')
-rw-r--r-- | crypto/initthread.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/crypto/initthread.c b/crypto/initthread.c index 1bdaeda9fc8e..27b460009e1d 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ #include "crypto/cryptlib.h" #include "prov/providercommon.h" #include "internal/thread_once.h" +#include "crypto/context.h" #ifdef FIPS_MODULE #include "prov/provider_ctx.h" @@ -26,7 +27,7 @@ * * The FIPS provider tells libcrypto about which threads it is interested in * by calling "c_thread_start" which is a function pointer created during - * provider initialisation (i.e. OSSL_init_provider). + * provider initialisation (i.e. OSSL_provider_init). */ extern OSSL_FUNC_core_thread_start_fn *c_thread_start; #endif @@ -248,7 +249,16 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) #else -static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx) +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; CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal)); @@ -256,9 +266,8 @@ static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx) if (tlocal == NULL) return NULL; - if (!CRYPTO_THREAD_init_local(tlocal, NULL)) { - goto err; - } + if (!CRYPTO_THREAD_init_local(tlocal, NULL)) + goto deinit; hands = OPENSSL_zalloc(sizeof(*hands)); if (hands == NULL) @@ -267,24 +276,31 @@ static void *thread_event_ossl_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); + CRYPTO_THREAD_cleanup_local(tlocal); + deinit: OPENSSL_free(tlocal); return NULL; } -static void thread_event_ossl_ctx_free(void *tlocal) +void ossl_thread_event_ctx_free(void *tlocal) { + CRYPTO_THREAD_cleanup_local(tlocal); OPENSSL_free(tlocal); } -static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = { - OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, - thread_event_ossl_ctx_new, - thread_event_ossl_ctx_free, -}; - static void ossl_arg_thread_stop(void *arg) { ossl_ctx_thread_stop((OSSL_LIB_CTX *)arg); @@ -294,8 +310,7 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) { THREAD_EVENT_HANDLER **hands; CRYPTO_THREAD_LOCAL *local - = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, - &thread_event_ossl_ctx_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX); if (local == NULL) return; @@ -363,8 +378,7 @@ int ossl_init_thread_start(const void *index, void *arg, * OSSL_LIB_CTX gets informed about thread stop events individually. */ CRYPTO_THREAD_LOCAL *local - = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, - &thread_event_ossl_ctx_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX); #else /* * Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per @@ -386,8 +400,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 |