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)
This commit is contained in:
Matt Caswell 2021-11-05 14:43:01 +00:00
parent c59fc87b33
commit 3b9de0c9aa

View File

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