mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-05-01 04:04:39 +00:00
Always ensure we hold ctx->lock when calling CRYPTO_get_ex_data()
Otherwise we can get data races. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13987)
This commit is contained in:
parent
b233ea8276
commit
04b9435a99
@ -283,7 +283,9 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index,
|
|||||||
|
|
||||||
if (dynidx != -1) {
|
if (dynidx != -1) {
|
||||||
CRYPTO_THREAD_read_lock(ctx->index_locks[index]);
|
CRYPTO_THREAD_read_lock(ctx->index_locks[index]);
|
||||||
|
CRYPTO_THREAD_read_lock(ctx->lock);
|
||||||
data = CRYPTO_get_ex_data(&ctx->data, dynidx);
|
data = CRYPTO_get_ex_data(&ctx->data, dynidx);
|
||||||
|
CRYPTO_THREAD_unlock(ctx->lock);
|
||||||
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -293,8 +295,8 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index,
|
|||||||
|
|
||||||
dynidx = ctx->dyn_indexes[index];
|
dynidx = ctx->dyn_indexes[index];
|
||||||
if (dynidx != -1) {
|
if (dynidx != -1) {
|
||||||
CRYPTO_THREAD_unlock(ctx->lock);
|
|
||||||
data = CRYPTO_get_ex_data(&ctx->data, dynidx);
|
data = CRYPTO_get_ex_data(&ctx->data, dynidx);
|
||||||
|
CRYPTO_THREAD_unlock(ctx->lock);
|
||||||
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -307,10 +309,22 @@ void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index,
|
|||||||
|
|
||||||
CRYPTO_THREAD_unlock(ctx->lock);
|
CRYPTO_THREAD_unlock(ctx->lock);
|
||||||
|
|
||||||
/* The alloc call ensures there's a value there */
|
/*
|
||||||
if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL,
|
* The alloc call ensures there's a value there. We release the ctx->lock
|
||||||
&ctx->data, ctx->dyn_indexes[index]))
|
* for this, because the allocation itself may recursively call
|
||||||
|
* ossl_lib_ctx_get_data for other indexes (never this one). The allocation
|
||||||
|
* will itself aquire the ctx->lock when it actually comes to store the
|
||||||
|
* allocated data (see ossl_lib_ctx_generic_new() above). We call
|
||||||
|
* ossl_crypto_alloc_ex_data_intern() here instead of CRYPTO_alloc_ex_data().
|
||||||
|
* They do the same thing except that the latter calls CRYPTO_get_ex_data()
|
||||||
|
* as well - which we must not do without holding the ctx->lock.
|
||||||
|
*/
|
||||||
|
if (ossl_crypto_alloc_ex_data_intern(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL,
|
||||||
|
&ctx->data, ctx->dyn_indexes[index])) {
|
||||||
|
CRYPTO_THREAD_read_lock(ctx->lock);
|
||||||
data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
|
data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
|
||||||
|
CRYPTO_THREAD_unlock(ctx->lock);
|
||||||
|
}
|
||||||
|
|
||||||
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
|
||||||
|
|
||||||
|
@ -392,16 +392,23 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
|||||||
int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
||||||
int idx)
|
int idx)
|
||||||
{
|
{
|
||||||
EX_CALLBACK *f;
|
|
||||||
EX_CALLBACKS *ip;
|
|
||||||
void *curval;
|
void *curval;
|
||||||
OSSL_EX_DATA_GLOBAL *global;
|
|
||||||
|
|
||||||
curval = CRYPTO_get_ex_data(ad, idx);
|
curval = CRYPTO_get_ex_data(ad, idx);
|
||||||
/* Already there, no need to allocate */
|
/* Already there, no need to allocate */
|
||||||
if (curval != NULL)
|
if (curval != NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
return ossl_crypto_alloc_ex_data_intern(class_index, obj, ad, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj,
|
||||||
|
CRYPTO_EX_DATA *ad, int idx)
|
||||||
|
{
|
||||||
|
EX_CALLBACK *f;
|
||||||
|
EX_CALLBACKS *ip;
|
||||||
|
OSSL_EX_DATA_GLOBAL *global;
|
||||||
|
|
||||||
global = ossl_lib_ctx_get_ex_data_global(ad->ctx);
|
global = ossl_lib_ctx_get_ex_data_global(ad->ctx);
|
||||||
if (global == NULL)
|
if (global == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -29,3 +29,6 @@ void ossl_ctx_thread_stop(void *arg);
|
|||||||
|
|
||||||
void ossl_trace_cleanup(void);
|
void ossl_trace_cleanup(void);
|
||||||
void ossl_malloc_setup_failures(void);
|
void ossl_malloc_setup_failures(void);
|
||||||
|
|
||||||
|
int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj,
|
||||||
|
CRYPTO_EX_DATA *ad, int idx);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user