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 <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15278)
This commit is contained in:
Matt Caswell 2021-05-20 11:52:56 +01:00 committed by Pauli
parent b3135f56a6
commit c9732f0953
4 changed files with 16 additions and 9 deletions

View File

@ -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

View File

@ -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);
}
/*

View File

@ -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

View File

@ -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))