From 43ed2429566f27a2fb030316201c0c7af5a2b966 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Tue, 1 Mar 2022 14:10:47 -0600 Subject: async_posix: Make ASYNC_set_mem_functions threadsafe Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/17762) --- crypto/async/arch/async_null.h | 2 ++ crypto/async/arch/async_posix.c | 30 ++++++++++++++++++++++++++++-- crypto/async/arch/async_posix.h | 3 +++ crypto/async/arch/async_win.h | 2 ++ crypto/async/async.c | 3 ++- 5 files changed, 37 insertions(+), 3 deletions(-) (limited to 'crypto/async') 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 # include # include +# include #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) -- cgit v1.2.3