diff options
author | Arran Cudbard-Bell <a.cudbardb@freeradius.org> | 2022-03-01 14:10:47 -0600 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2022-03-10 13:54:07 +0000 |
commit | 43ed2429566f27a2fb030316201c0c7af5a2b966 (patch) | |
tree | f3c3e8003a269b9a1a9d229b0bf4a80575f234dc | |
parent | f6f56f4776727e18d4dd5490e3b507bae068013a (diff) |
async_posix: Make ASYNC_set_mem_functions threadsafe
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17762)
-rw-r--r-- | crypto/async/arch/async_null.h | 2 | ||||
-rw-r--r-- | crypto/async/arch/async_posix.c | 30 | ||||
-rw-r--r-- | crypto/async/arch/async_posix.h | 3 | ||||
-rw-r--r-- | crypto/async/arch/async_win.h | 2 | ||||
-rw-r--r-- | crypto/async/async.c | 3 |
5 files changed, 37 insertions, 3 deletions
diff --git a/crypto/async/arch/async_null.h b/crypto/async/arch/async_null.h index c62aba69a8..2b83932ebc 100644 --- a/crypto/async/arch/async_null.h +++ b/crypto/async/arch/async_null.h @@ -26,5 +26,7 @@ typedef struct async_fibre_st { # define async_fibre_makecontext(c) 0 # define async_fibre_free(f) # define async_fibre_init_dispatcher(f) +# define async_local_init() 1 +# define async_local_deinit() #endif diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index 0a1ffbf8d0..22be25f172 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -15,12 +15,26 @@ # include <stddef.h> # include <unistd.h> # include <openssl/err.h> +# include <openssl/crypto.h> #define STACKSIZE 32768 +static CRYPTO_RWLOCK *async_mem_lock; + static void *async_stack_alloc(size_t *num); static void async_stack_free(void *addr); +int async_local_init(void) +{ + async_mem_lock = CRYPTO_THREAD_lock_new(); + return async_mem_lock != NULL; +} + +void async_local_deinit(void) +{ + CRYPTO_THREAD_lock_free(async_mem_lock); +} + static int allow_customize = 1; static ASYNC_stack_alloc_fn stack_alloc_impl = async_stack_alloc; static ASYNC_stack_free_fn stack_free_impl = async_stack_free; @@ -39,8 +53,16 @@ int ASYNC_is_capable(void) int ASYNC_set_mem_functions(ASYNC_stack_alloc_fn alloc_fn, ASYNC_stack_free_fn free_fn) { - if (!allow_customize) + OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL); + + if (!CRYPTO_THREAD_write_lock(async_mem_lock)) + return 0; + if (!allow_customize) { + CRYPTO_THREAD_unlock(async_mem_lock); return 0; + } + CRYPTO_THREAD_unlock(async_mem_lock); + if (alloc_fn != NULL) stack_alloc_impl = alloc_fn; if (free_fn != NULL) @@ -83,8 +105,12 @@ int async_fibre_makecontext(async_fibre *fibre) * Disallow customisation after the first * stack is allocated. */ - if (allow_customize) + if (allow_customize) { + if (!CRYPTO_THREAD_write_lock(async_mem_lock)) + return 0; allow_customize = 0; + CRYPTO_THREAD_unlock(async_mem_lock); + } fibre->fibre.uc_stack.ss_sp = stack_alloc_impl(&num); if (fibre->fibre.uc_stack.ss_sp != NULL) { diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h index 57da6e211f..1f681851eb 100644 --- a/crypto/async/arch/async_posix.h +++ b/crypto/async/arch/async_posix.h @@ -61,6 +61,9 @@ typedef struct async_fibre_st { # endif } async_fibre; +int async_local_init(void); +void async_local_deinit(void); + static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r) { # ifdef USE_SWAPCONTEXT diff --git a/crypto/async/arch/async_win.h b/crypto/async/arch/async_win.h index 0fab95996e..24ed9de657 100644 --- a/crypto/async/arch/async_win.h +++ b/crypto/async/arch/async_win.h @@ -37,6 +37,8 @@ typedef struct async_fibre_st { # endif # define async_fibre_free(f) (DeleteFiber((f)->fibre)) +# define async_local_init() 1 +# define async_local_deinit() int async_fibre_init_dispatcher(async_fibre *fibre); VOID CALLBACK async_start_func_win(PVOID unused); diff --git a/crypto/async/async.c b/crypto/async/async.c index a320d455b7..d0e383536c 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -340,13 +340,14 @@ int async_init(void) return 0; } - return 1; + return async_local_init(); } void async_deinit(void) { CRYPTO_THREAD_cleanup_local(&ctxkey); CRYPTO_THREAD_cleanup_local(&poolkey); + async_local_deinit(); } int ASYNC_init_thread(size_t max_size, size_t init_size) |