summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>2022-03-01 14:10:47 -0600
committerMatt Caswell <matt@openssl.org>2022-03-10 13:54:07 +0000
commit43ed2429566f27a2fb030316201c0c7af5a2b966 (patch)
treef3c3e8003a269b9a1a9d229b0bf4a80575f234dc /crypto
parentf6f56f4776727e18d4dd5490e3b507bae068013a (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)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/async/arch/async_null.h2
-rw-r--r--crypto/async/arch/async_posix.c30
-rw-r--r--crypto/async/arch/async_posix.h3
-rw-r--r--crypto/async/arch/async_win.h2
-rw-r--r--crypto/async/async.c3
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)