From: Matt Caswell Date: Thu, 20 May 2021 10:52:56 +0000 (+0100) Subject: Fix a memleak in the FIPS provider X-Git-Tag: openssl-3.0.0-beta1~419 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c9732f095363251131e6e6a4cbbe45deea285ed0;p=thirdparty%2Fopenssl.git Fix a memleak in the FIPS provider If the DRBG is used within the scope of the FIPS OSSL_provider_init function then it attempts to register a thread callback via c_thread_start. However the implementation of c_thread_start assumed that the provider's provctx was already present. However because OSSL_provider_init is still running it was actually NULL. This means the thread callback fail to work correctly and a memory leak resulted. Instead of having c_thread_start use the provctx as the callback argument we change the definition of c_thread_start to have an explicit callback argument to use. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15278) --- diff --git a/crypto/initthread.c b/crypto/initthread.c index 73f55c5cb8e..d86e280fc13 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -237,12 +237,12 @@ void OPENSSL_thread_stop(void) } } -void ossl_ctx_thread_stop(void *arg) +void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) { if (destructor_key.sane != -1) { THREAD_EVENT_HANDLER **hands = init_get_thread_local(&destructor_key.value, 0, 1); - init_thread_stop(arg, hands); + init_thread_stop(ctx, hands); } } @@ -285,10 +285,14 @@ static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = { thread_event_ossl_ctx_free, }; -void ossl_ctx_thread_stop(void *arg) +static void ossl_arg_thread_stop(void *arg) +{ + ossl_ctx_thread_stop((OSSL_LIB_CTX *)arg); +} + +void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx) { THREAD_EVENT_HANDLER **hands; - OSSL_LIB_CTX *ctx = PROV_LIBCTX_OF(arg); CRYPTO_THREAD_LOCAL *local = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, &thread_event_ossl_ctx_method); @@ -367,7 +371,8 @@ 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_ctx_thread_stop)) + if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_arg_thread_stop, + ctx)) return 0; } #endif diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 512a16ee662..ca2bfdb8fac 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -1603,7 +1603,8 @@ static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle) } static int core_thread_start(const OSSL_CORE_HANDLE *handle, - OSSL_thread_stop_handler_fn handfn) + OSSL_thread_stop_handler_fn handfn, + void *arg) { /* * We created this object originally and we know it is actually an @@ -1611,7 +1612,7 @@ static int core_thread_start(const OSSL_CORE_HANDLE *handle, */ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; - return ossl_init_thread_start(prov, prov->provctx, handfn); + return ossl_init_thread_start(prov, arg, handfn); } /* diff --git a/include/crypto/cryptlib.h b/include/crypto/cryptlib.h index 1e58663b4fc..39a956bfd36 100644 --- a/include/crypto/cryptlib.h +++ b/include/crypto/cryptlib.h @@ -21,7 +21,7 @@ int ossl_init_thread_start(const void *index, void *arg, int ossl_init_thread_deregister(void *index); int ossl_init_thread(void); void ossl_cleanup_thread(void); -void ossl_ctx_thread_stop(void *arg); +void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx); /* * OPENSSL_INIT flags. The primary list of these is in crypto.h. Flags below diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 458cbb1c9e2..2a46c101231 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -68,7 +68,8 @@ OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_CORE_HANDLE *prov, OSSL_PARAM params[])) # define OSSL_FUNC_CORE_THREAD_START 3 OSSL_CORE_MAKE_FUNC(int,core_thread_start,(const OSSL_CORE_HANDLE *prov, - OSSL_thread_stop_handler_fn handfn)) + OSSL_thread_stop_handler_fn handfn, + void *arg)) # define OSSL_FUNC_CORE_GET_LIBCTX 4 OSSL_CORE_MAKE_FUNC(OPENSSL_CORE_CTX *,core_get_libctx, (const OSSL_CORE_HANDLE *prov))