Patch-Source: https://github.com/erlang/otp/pull/7450 https://github.com/erlang/otp/issues/7436 -- From fae85c2e38795c4d681ca010fb28a559c21375df Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 28 Jun 2023 15:52:30 +0200 Subject: [PATCH] crypto: Fix segv crash after purge-reload of crypto on musl Symptom: Different kind of segv crashes after crypto is loaded, purged and loaded again. Problem: dlclose on musl libc is a no-op. Mutex 'mtx_init_curve_types' was destroyed at unload and then not re-created at reload as static variable `library_initialized` in crypto.c is true because musl dlclose is a no-op and dlopen reuses the existing loaded crypto.so library with static variables intact. --- lib/crypto/c_src/algorithms.c | 17 ++++++++++++++--- lib/crypto/c_src/algorithms.h | 3 ++- lib/crypto/c_src/crypto.c | 4 +++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c index 53b574af3aff..188b6c30a124 100644 --- a/lib/crypto/c_src/algorithms.c +++ b/lib/crypto/c_src/algorithms.c @@ -51,7 +51,6 @@ void init_rsa_opts_types(ErlNifEnv* env); void init_algorithms_types(ErlNifEnv* env) { - mtx_init_curve_types = enif_mutex_create("init_curve_types"); #ifdef HAS_3_0_API #else init_hash_types(env); @@ -62,9 +61,21 @@ void init_algorithms_types(ErlNifEnv* env) /* ciphers and macs are initiated statically */ } -void cleanup_algorithms_types(ErlNifEnv* env) + +int create_curve_mutex(void) +{ + if (!mtx_init_curve_types) { + mtx_init_curve_types = enif_mutex_create("init_curve_types"); + } + return !!mtx_init_curve_types; +} + +void destroy_curve_mutex(void) { - enif_mutex_destroy(mtx_init_curve_types); + if (mtx_init_curve_types) { + enif_mutex_destroy(mtx_init_curve_types); + mtx_init_curve_types = NULL; + } } /*================================================================ diff --git a/lib/crypto/c_src/algorithms.h b/lib/crypto/c_src/algorithms.h index 25e1db129955..3c22a9fccc42 100644 --- a/lib/crypto/c_src/algorithms.h +++ b/lib/crypto/c_src/algorithms.h @@ -23,8 +23,9 @@ #include "common.h" +int create_curve_mutex(void); +void destroy_curve_mutex(void); void init_algorithms_types(ErlNifEnv* env); -void cleanup_algorithms_types(ErlNifEnv* env); ERL_NIF_TERM hash_algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM pubkey_algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index a21e9aaf204c..f1ccacfbac79 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -214,6 +214,8 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info) if (!create_engine_mutex(env)) { return __LINE__; } + if (!create_curve_mutex()) + return __LINE__; #ifdef HAS_3_0_API prov_cnt = 0; @@ -329,7 +331,7 @@ static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, static void unload(ErlNifEnv* env, void* priv_data) { if (--library_refc == 0) { - cleanup_algorithms_types(env); + destroy_curve_mutex(); destroy_engine_mutex(env); }