mirror of https://github.com/openssl/openssl.git
Move thread-event handlers to the new thread-local api
Thread event handlers in the fips provider create a thread-local storage key per context, meaning we can exhaust our thread-local space quickly by creating lots of contexts. Avoid that by moving to the new thread-local storage api. Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/27794)
This commit is contained in:
parent
ce990ce83b
commit
2e74a3045b
|
@ -16,6 +16,7 @@
|
|||
#include "internal/core.h"
|
||||
#include "internal/bio.h"
|
||||
#include "internal/provider.h"
|
||||
#include "internal/threads_common.h"
|
||||
#include "crypto/decoder.h"
|
||||
#include "crypto/context.h"
|
||||
|
||||
|
@ -31,7 +32,6 @@ struct ossl_lib_ctx_st {
|
|||
void *global_properties;
|
||||
void *drbg;
|
||||
void *drbg_nonce;
|
||||
CRYPTO_THREAD_LOCAL rcu_local_key;
|
||||
#ifndef FIPS_MODULE
|
||||
void *provider_conf;
|
||||
void *bio_core;
|
||||
|
@ -47,7 +47,6 @@ struct ossl_lib_ctx_st {
|
|||
void *threads;
|
||||
#endif
|
||||
#ifdef FIPS_MODULE
|
||||
void *thread_event_handler;
|
||||
void *fips_prov;
|
||||
#endif
|
||||
STACK_OF(SSL_COMP) *comp_methods;
|
||||
|
@ -92,9 +91,6 @@ static int context_init(OSSL_LIB_CTX *ctx)
|
|||
{
|
||||
int exdata_done = 0;
|
||||
|
||||
if (!CRYPTO_THREAD_init_local(&ctx->rcu_local_key, NULL))
|
||||
return 0;
|
||||
|
||||
ctx->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ctx->lock == NULL)
|
||||
goto err;
|
||||
|
@ -187,8 +183,7 @@ static int context_init(OSSL_LIB_CTX *ctx)
|
|||
#endif
|
||||
|
||||
#ifdef FIPS_MODULE
|
||||
ctx->thread_event_handler = ossl_thread_event_ctx_new(ctx);
|
||||
if (ctx->thread_event_handler == NULL)
|
||||
if (!ossl_thread_event_ctx_new(ctx))
|
||||
goto err;
|
||||
|
||||
ctx->fips_prov = ossl_fips_prov_ossl_ctx_new(ctx);
|
||||
|
@ -226,7 +221,6 @@ static int context_init(OSSL_LIB_CTX *ctx)
|
|||
ossl_crypto_cleanup_all_ex_data_int(ctx);
|
||||
|
||||
CRYPTO_THREAD_lock_free(ctx->lock);
|
||||
CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
|
||||
memset(ctx, '\0', sizeof(*ctx));
|
||||
return 0;
|
||||
}
|
||||
|
@ -331,10 +325,7 @@ static void context_deinit_objs(OSSL_LIB_CTX *ctx)
|
|||
#endif
|
||||
|
||||
#ifdef FIPS_MODULE
|
||||
if (ctx->thread_event_handler != NULL) {
|
||||
ossl_thread_event_ctx_free(ctx->thread_event_handler);
|
||||
ctx->thread_event_handler = NULL;
|
||||
}
|
||||
ossl_thread_event_ctx_free(ctx);
|
||||
|
||||
if (ctx->fips_prov != NULL) {
|
||||
ossl_fips_prov_ossl_ctx_free(ctx->fips_prov);
|
||||
|
@ -379,7 +370,6 @@ static int context_deinit(OSSL_LIB_CTX *ctx)
|
|||
|
||||
CRYPTO_THREAD_lock_free(ctx->lock);
|
||||
ctx->lock = NULL;
|
||||
CRYPTO_THREAD_cleanup_local(&ctx->rcu_local_key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -388,24 +378,15 @@ static int context_deinit(OSSL_LIB_CTX *ctx)
|
|||
static OSSL_LIB_CTX default_context_int;
|
||||
|
||||
static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
|
||||
static CRYPTO_THREAD_LOCAL default_context_thread_local;
|
||||
static int default_context_inited = 0;
|
||||
|
||||
DEFINE_RUN_ONCE_STATIC(default_context_do_init)
|
||||
{
|
||||
if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL))
|
||||
goto err;
|
||||
|
||||
if (!context_init(&default_context_int))
|
||||
goto deinit_thread;
|
||||
return 0;
|
||||
|
||||
default_context_inited = 1;
|
||||
return 1;
|
||||
|
||||
deinit_thread:
|
||||
CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ossl_lib_ctx_default_deinit(void)
|
||||
|
@ -413,7 +394,6 @@ void ossl_lib_ctx_default_deinit(void)
|
|||
if (!default_context_inited)
|
||||
return;
|
||||
context_deinit(&default_context_int);
|
||||
CRYPTO_THREAD_cleanup_local(&default_context_thread_local);
|
||||
default_context_inited = 0;
|
||||
}
|
||||
|
||||
|
@ -422,7 +402,7 @@ static OSSL_LIB_CTX *get_thread_default_context(void)
|
|||
if (!RUN_ONCE(&default_context_init, default_context_do_init))
|
||||
return NULL;
|
||||
|
||||
return CRYPTO_THREAD_get_local(&default_context_thread_local);
|
||||
return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY, NULL);
|
||||
}
|
||||
|
||||
static OSSL_LIB_CTX *get_default_context(void)
|
||||
|
@ -439,7 +419,7 @@ static int set_default_context(OSSL_LIB_CTX *defctx)
|
|||
if (defctx == &default_context_int)
|
||||
defctx = NULL;
|
||||
|
||||
return CRYPTO_THREAD_set_local(&default_context_thread_local, defctx);
|
||||
return CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY, NULL, defctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -615,9 +595,6 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index)
|
|||
#endif
|
||||
|
||||
#ifdef FIPS_MODULE
|
||||
case OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX:
|
||||
return ctx->thread_event_handler;
|
||||
|
||||
case OSSL_LIB_CTX_FIPS_PROV_INDEX:
|
||||
return ctx->fips_prov;
|
||||
#endif
|
||||
|
@ -656,14 +633,6 @@ const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx)
|
|||
#endif
|
||||
}
|
||||
|
||||
CRYPTO_THREAD_LOCAL *ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX *libctx)
|
||||
{
|
||||
libctx = ossl_lib_ctx_get_concrete(libctx);
|
||||
if (libctx == NULL)
|
||||
return NULL;
|
||||
return &libctx->rcu_local_key;
|
||||
}
|
||||
|
||||
int OSSL_LIB_CTX_get_conf_diagnostics(OSSL_LIB_CTX *libctx)
|
||||
{
|
||||
libctx = ossl_lib_ctx_get_concrete(libctx);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "crypto/cryptlib.h"
|
||||
#include "prov/providercommon.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/threads_common.h"
|
||||
#include "crypto/context.h"
|
||||
|
||||
#ifdef FIPS_MODULE
|
||||
|
@ -90,6 +91,7 @@ static int init_thread_deregister(void *arg, int all);
|
|||
#endif
|
||||
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
static THREAD_EVENT_HANDLER **
|
||||
init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
|
||||
{
|
||||
|
@ -106,13 +108,11 @@ init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
if (!init_thread_push_handlers(hands)) {
|
||||
CRYPTO_THREAD_set_local(local, NULL);
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (!keep) {
|
||||
CRYPTO_THREAD_set_local(local, NULL);
|
||||
|
@ -121,6 +121,32 @@ init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
|
|||
return hands;
|
||||
}
|
||||
|
||||
#else
|
||||
static THREAD_EVENT_HANDLER **
|
||||
init_get_thread_local_ex(OSSL_LIB_CTX *ctx, int alloc, int keep)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx);
|
||||
|
||||
if (alloc) {
|
||||
if (hands == NULL) {
|
||||
|
||||
if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, hands)) {
|
||||
OPENSSL_free(hands);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (!keep) {
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, NULL);
|
||||
}
|
||||
|
||||
return hands;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
/*
|
||||
* Since per-thread-specific-data destructors are not universally
|
||||
|
@ -258,22 +284,15 @@ int ossl_thread_register_fips(OSSL_LIB_CTX *libctx)
|
|||
libctx);
|
||||
}
|
||||
|
||||
void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
|
||||
int ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands = NULL;
|
||||
CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal));
|
||||
|
||||
if (tlocal == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!CRYPTO_THREAD_init_local(tlocal, NULL))
|
||||
goto deinit;
|
||||
|
||||
hands = OPENSSL_zalloc(sizeof(*hands));
|
||||
if (hands == NULL)
|
||||
goto err;
|
||||
|
||||
if (!CRYPTO_THREAD_set_local(tlocal, hands))
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, libctx, hands))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
|
@ -286,19 +305,15 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx)
|
|||
* function.
|
||||
*/
|
||||
|
||||
return tlocal;
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_free(hands);
|
||||
CRYPTO_THREAD_cleanup_local(tlocal);
|
||||
deinit:
|
||||
OPENSSL_free(tlocal);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ossl_thread_event_ctx_free(void *tlocal)
|
||||
void ossl_thread_event_ctx_free(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
CRYPTO_THREAD_cleanup_local(tlocal);
|
||||
OPENSSL_free(tlocal);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_TEVENT_KEY, ctx, NULL);
|
||||
}
|
||||
|
||||
static void ossl_arg_thread_stop(void *arg)
|
||||
|
@ -309,12 +324,8 @@ static void ossl_arg_thread_stop(void *arg)
|
|||
void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
THREAD_EVENT_HANDLER **hands;
|
||||
CRYPTO_THREAD_LOCAL *local
|
||||
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX);
|
||||
|
||||
if (local == NULL)
|
||||
return;
|
||||
hands = init_get_thread_local(local, 0, 0);
|
||||
hands = init_get_thread_local_ex(ctx, 0, 0);
|
||||
init_thread_stop(ctx, hands);
|
||||
OPENSSL_free(hands);
|
||||
}
|
||||
|
@ -377,8 +388,7 @@ int ossl_init_thread_start(const void *index, void *arg,
|
|||
* of OSSL_LIB_CTX and thread. This is because in FIPS mode each
|
||||
* OSSL_LIB_CTX gets informed about thread stop events individually.
|
||||
*/
|
||||
CRYPTO_THREAD_LOCAL *local
|
||||
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX);
|
||||
hands = init_get_thread_local_ex(ctx, 1, 0);
|
||||
#else
|
||||
/*
|
||||
* Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per
|
||||
|
@ -387,9 +397,9 @@ int ossl_init_thread_start(const void *index, void *arg,
|
|||
* OSSL_LIB_CTXs are informed.
|
||||
*/
|
||||
CRYPTO_THREAD_LOCAL *local = &destructor_key.value;
|
||||
hands = init_get_thread_local(local, 1, 0);
|
||||
#endif
|
||||
|
||||
hands = init_get_thread_local(local, 1, 0);
|
||||
if (hands == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *);
|
|||
void *ossl_indicator_set_callback_new(OSSL_LIB_CTX *);
|
||||
void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *);
|
||||
int ossl_thread_register_fips(OSSL_LIB_CTX *);
|
||||
void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *);
|
||||
int ossl_thread_event_ctx_new(OSSL_LIB_CTX *);
|
||||
void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *);
|
||||
#if defined(OPENSSL_THREADS)
|
||||
void *ossl_threads_ctx_new(OSSL_LIB_CTX *);
|
||||
|
@ -42,7 +42,7 @@ void ossl_prov_drbg_nonce_ctx_free(void *);
|
|||
void ossl_indicator_set_callback_free(void *cb);
|
||||
void ossl_self_test_set_callback_free(void *);
|
||||
void ossl_rand_crng_ctx_free(void *);
|
||||
void ossl_thread_event_ctx_free(void *);
|
||||
void ossl_thread_event_ctx_free(OSSL_LIB_CTX *);
|
||||
void ossl_fips_prov_ossl_ctx_free(void *);
|
||||
void ossl_release_default_drbg_ctx(void);
|
||||
#if defined(OPENSSL_THREADS)
|
||||
|
|
|
@ -103,9 +103,9 @@ typedef struct ossl_ex_data_global_st {
|
|||
# define OSSL_LIB_CTX_DRBG_INDEX 5
|
||||
# define OSSL_LIB_CTX_DRBG_NONCE_INDEX 6
|
||||
/* slot 7 unused, was CRNG test data and can be reused */
|
||||
# ifdef FIPS_MODULE
|
||||
# define OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX 8
|
||||
# endif
|
||||
/*
|
||||
* slot 8 unused, was OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX
|
||||
*/
|
||||
# define OSSL_LIB_CTX_FIPS_PROV_INDEX 9
|
||||
# define OSSL_LIB_CTX_ENCODER_STORE_INDEX 10
|
||||
# define OSSL_LIB_CTX_DECODER_STORE_INDEX 11
|
||||
|
@ -133,7 +133,6 @@ void ossl_lib_ctx_default_deinit(void);
|
|||
OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx);
|
||||
|
||||
const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx);
|
||||
CRYPTO_THREAD_LOCAL *ossl_lib_ctx_get_rcukey(OSSL_LIB_CTX *libctx);
|
||||
|
||||
OSSL_LIB_CTX *ossl_crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad);
|
||||
int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj,
|
||||
|
|
Loading…
Reference in New Issue