summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-05-20 11:52:56 +0100
committerPauli <pauli@openssl.org>2021-05-24 09:39:15 +1000
commitc9732f095363251131e6e6a4cbbe45deea285ed0 (patch)
treef79bc658c3ef64ec292e41bb9d0f87a5edf27ac4
parentb3135f56a663711a1234e3d419aaae5fe6915f7f (diff)
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)
-rw-r--r--crypto/initthread.c15
-rw-r--r--crypto/provider_core.c5
-rw-r--r--include/crypto/cryptlib.h2
-rw-r--r--include/openssl/core_dispatch.h3
4 files changed, 16 insertions, 9 deletions
diff --git a/crypto/initthread.c b/crypto/initthread.c
index 73f55c5cb8..d86e280fc1 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 512a16ee66..ca2bfdb8fa 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 1e58663b4f..39a956bfd3 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 458cbb1c9e..2a46c10123 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))