mirror of
https://github.com/openssl/openssl.git
synced 2026-06-06 20:18:09 +00:00
Allow for differentiating between default and NULL context
Allow for use of default context in the thread-local api by using get_concrete This creates a problem however in that get_concrete access a thread-local api, creating a recursive call that exhausts stack space So create a special context token that identifys the no context use case when we want to store thread-local data without an explicit context index 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:
+17
-9
@@ -44,7 +44,8 @@ static async_ctx *async_ctx_new(void)
|
||||
async_fibre_init_dispatcher(&nctx->dispatcher);
|
||||
nctx->currjob = NULL;
|
||||
nctx->blocked = 0;
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY, NULL, nctx))
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, nctx))
|
||||
goto err;
|
||||
|
||||
return nctx;
|
||||
@@ -56,7 +57,8 @@ err:
|
||||
|
||||
async_ctx *async_get_ctx(void)
|
||||
{
|
||||
return (async_ctx *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY, NULL);
|
||||
return (async_ctx *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static int async_ctx_free(void)
|
||||
@@ -65,7 +67,8 @@ static int async_ctx_free(void)
|
||||
|
||||
ctx = async_get_ctx();
|
||||
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY, NULL, NULL))
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_CTX_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, NULL))
|
||||
return 0;
|
||||
|
||||
OPENSSL_free(ctx);
|
||||
@@ -99,7 +102,8 @@ static ASYNC_JOB *async_get_pool_job(void) {
|
||||
ASYNC_JOB *job;
|
||||
async_pool *pool;
|
||||
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY, NULL);
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
if (pool == NULL) {
|
||||
/*
|
||||
* Pool has not been initialised, so init with the defaults, i.e.
|
||||
@@ -107,7 +111,8 @@ static ASYNC_JOB *async_get_pool_job(void) {
|
||||
*/
|
||||
if (ASYNC_init_thread(0, 0) == 0)
|
||||
return NULL;
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY, NULL);
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
}
|
||||
|
||||
job = sk_ASYNC_JOB_pop(pool->jobs);
|
||||
@@ -131,7 +136,8 @@ static ASYNC_JOB *async_get_pool_job(void) {
|
||||
static void async_release_job(ASYNC_JOB *job) {
|
||||
async_pool *pool;
|
||||
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY, NULL);
|
||||
pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
if (pool == NULL) {
|
||||
ERR_raise(ERR_LIB_ASYNC, ERR_R_INTERNAL_ERROR);
|
||||
return;
|
||||
@@ -379,7 +385,8 @@ int ASYNC_init_thread(size_t max_size, size_t init_size)
|
||||
curr_size++;
|
||||
}
|
||||
pool->curr_size = curr_size;
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY, NULL, pool)) {
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, pool)) {
|
||||
ERR_raise(ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL);
|
||||
goto err;
|
||||
}
|
||||
@@ -395,13 +402,14 @@ err:
|
||||
static void async_delete_thread_state(void *arg)
|
||||
{
|
||||
async_pool *pool = (async_pool *)CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
NULL);
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
|
||||
if (pool != NULL) {
|
||||
async_empty_pool(pool);
|
||||
sk_ASYNC_JOB_free(pool->jobs);
|
||||
OPENSSL_free(pool);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY, NULL, NULL);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ASYNC_POOL_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, NULL);
|
||||
}
|
||||
async_local_cleanup();
|
||||
async_ctx_free();
|
||||
|
||||
+4
-2
@@ -402,7 +402,8 @@ 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_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY, NULL);
|
||||
return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static OSSL_LIB_CTX *get_default_context(void)
|
||||
@@ -419,7 +420,8 @@ static int set_default_context(OSSL_LIB_CTX *defctx)
|
||||
if (defctx == &default_context_int)
|
||||
defctx = NULL;
|
||||
|
||||
return CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY, NULL, defctx);
|
||||
return CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DEF_CTX_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, defctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+20
-10
@@ -638,12 +638,14 @@ const char *ERR_reason_error_string(unsigned long e)
|
||||
|
||||
static void err_delete_thread_state(void *unused)
|
||||
{
|
||||
ERR_STATE *state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL);
|
||||
ERR_STATE *state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, NULL);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, NULL);
|
||||
OSSL_ERR_STATE_free(state);
|
||||
}
|
||||
|
||||
@@ -667,24 +669,29 @@ ERR_STATE *ossl_err_get_state_int(void)
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL))
|
||||
return NULL;
|
||||
|
||||
state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL);
|
||||
state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
if (state == (ERR_STATE *)-1)
|
||||
return NULL;
|
||||
|
||||
if (state == NULL) {
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, (ERR_STATE *)-1))
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, (ERR_STATE *)-1))
|
||||
return NULL;
|
||||
|
||||
state = OSSL_ERR_STATE_new();
|
||||
if (state == NULL) {
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, NULL);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ossl_init_thread_start(NULL, NULL, err_delete_thread_state)
|
||||
|| !CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, state)) {
|
||||
|| !CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, state)) {
|
||||
OSSL_ERR_STATE_free(state);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, NULL);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -727,8 +734,10 @@ int err_shelve_state(void **state)
|
||||
if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL))
|
||||
return 0;
|
||||
|
||||
*state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL);
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, (ERR_STATE *)-1))
|
||||
*state = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT);
|
||||
if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, (ERR_STATE *)-1))
|
||||
return 0;
|
||||
|
||||
set_sys_error(saveerrno);
|
||||
@@ -742,7 +751,8 @@ int err_shelve_state(void **state)
|
||||
void err_unshelve_state(void* state)
|
||||
{
|
||||
if (state != (void*)-1)
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY, NULL, (ERR_STATE *)state);
|
||||
CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_ERR_KEY,
|
||||
CRYPTO_THREAD_NO_CONTEXT, (ERR_STATE *)state);
|
||||
}
|
||||
|
||||
int ERR_get_next_error_library(void)
|
||||
|
||||
@@ -256,6 +256,7 @@ void *CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_KEY_ID id, OSSL_LIB_CTX *ct
|
||||
MASTER_KEY_ENTRY *mkey;
|
||||
CTX_TABLE_ENTRY ctxd;
|
||||
|
||||
ctx = (ctx == CRYPTO_THREAD_NO_CONTEXT) ? NULL : ossl_lib_ctx_get_concrete(ctx);
|
||||
/*
|
||||
* Make sure the master key has been initialized
|
||||
* NOTE: We use CRYPTO_THREAD_run_once here, rather than the
|
||||
@@ -333,6 +334,7 @@ int CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_KEY_ID id,
|
||||
{
|
||||
MASTER_KEY_ENTRY *mkey;
|
||||
|
||||
ctx = (ctx == CRYPTO_THREAD_NO_CONTEXT) ? NULL : ossl_lib_ctx_get_concrete(ctx);
|
||||
/*
|
||||
* Make sure our master key is initialized
|
||||
* See notes above on the use of CRYPTO_THREAD_run_once here
|
||||
|
||||
@@ -22,6 +22,8 @@ typedef enum {
|
||||
CRYPTO_THREAD_LOCAL_KEY_MAX
|
||||
} CRYPTO_THREAD_LOCAL_KEY_ID;
|
||||
|
||||
#define CRYPTO_THREAD_NO_CONTEXT (void *)1
|
||||
|
||||
void *CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_KEY_ID id,
|
||||
OSSL_LIB_CTX *ctx);
|
||||
int CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_KEY_ID id,
|
||||
|
||||
Reference in New Issue
Block a user