summaryrefslogtreecommitdiffstats
path: root/crypto/initthread.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-11-05 14:43:01 +0000
committerMatt Caswell <matt@openssl.org>2021-11-12 17:16:14 +0000
commit3b9de0c9aa791bd9e6f0534ec091accbdf15292f (patch)
tree3404f0f85f4d4b928c9bb8596d7a320b391deaea /crypto/initthread.c
parentc59fc87b338880893286934f02c446854f5baabf (diff)
Avoid a race in init_thread_stop()
init_thread_stop() is called when a thread is stopping. It calls all the callbacks that need to know about the demise of this thread. However, the list of callbacks is also available globally and may be updated by other threads so we need to make sure we use the right lock. Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16980)
Diffstat (limited to 'crypto/initthread.c')
-rw-r--r--crypto/initthread.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/crypto/initthread.c b/crypto/initthread.c
index d86e280fc1..1bdaeda9fc 100644
--- a/crypto/initthread.c
+++ b/crypto/initthread.c
@@ -309,11 +309,23 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands)
{
THREAD_EVENT_HANDLER *curr, *prev = NULL, *tmp;
+#ifndef FIPS_MODULE
+ GLOBAL_TEVENT_REGISTER *gtr;
+#endif
/* Can't do much about this */
if (hands == NULL)
return;
+#ifndef FIPS_MODULE
+ gtr = get_global_tevent_register();
+ if (gtr == NULL)
+ return;
+
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return;
+#endif
+
curr = *hands;
while (curr != NULL) {
if (arg != NULL && curr->arg != arg) {
@@ -332,6 +344,9 @@ static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands)
OPENSSL_free(tmp);
}
+#ifndef FIPS_MODULE
+ CRYPTO_THREAD_unlock(gtr->lock);
+#endif
}
int ossl_init_thread_start(const void *index, void *arg,