/*
- * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include "internal/thread_once.h"
#ifdef FIPS_MODULE
+#include "prov/provider_ctx.h"
+
/*
* Thread aware code may want to be told about thread stop events. We register
* to hear about those thread stop events when we see a new thread has started.
typedef struct thread_event_handler_st THREAD_EVENT_HANDLER;
struct thread_event_handler_st {
+#ifndef FIPS_MODULE
const void *index;
+#endif
void *arg;
OSSL_thread_stop_handler_fn handfn;
THREAD_EVENT_HANDLER *next;
if (gtr == NULL)
return 0;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
CRYPTO_THREAD_unlock(gtr->lock);
gtr = get_global_tevent_register();
if (gtr == NULL)
return;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return;
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
if (hands == handsin) {
- hands = sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i);
+ sk_THREAD_EVENT_HANDLER_PTR_delete(gtr->skhands, i);
CRYPTO_THREAD_unlock(gtr->lock);
return;
}
{
ctx = ossl_lib_ctx_get_concrete(ctx);
/*
- * TODO(3.0). It would be nice if we could figure out a way to do this on
- * all threads that have used the OSSL_LIB_CTX when the context is freed.
- * This is currently not possible due to the use of thread local variables.
+ * It would be nice if we could figure out a way to do this on all threads
+ * that have used the OSSL_LIB_CTX when the context is freed. This is
+ * currently not possible due to the use of thread local variables.
*/
ossl_ctx_thread_stop(ctx);
}
}
}
-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);
}
}
}
static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = {
+ OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
thread_event_ossl_ctx_new,
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 = arg;
CRYPTO_THREAD_LOCAL *local
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX,
&thread_event_ossl_ctx_method);
if (local == NULL)
return;
hands = init_get_thread_local(local, 0, 0);
- init_thread_stop(arg, hands);
+ init_thread_stop(ctx, hands);
OPENSSL_free(hands);
}
#endif /* FIPS_MODULE */
* 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
hand->handfn = handfn;
hand->arg = arg;
+#ifndef FIPS_MODULE
hand->index = index;
+#endif
hand->next = *hands;
*hands = hand;
gtr = get_global_tevent_register();
if (gtr == NULL)
return 0;
- if (!all)
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!all) {
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
+ } else {
+ glob_tevent_reg = NULL;
+ }
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);