diff options
author | Erlang/OTP <otp@erlang.org> | 2021-10-04 17:12:00 +0200 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2021-10-04 17:12:00 +0200 |
commit | a5109ba45402d9cd215ea3d3f56c4a2c488d6593 (patch) | |
tree | f680b87b9b743172e4c34f371f65f3b0ca3ff389 | |
parent | 9a0896352c46b6fd325968dd43a91147ad2dfd94 (diff) | |
parent | e1625b615f61932da9f9da88717fcde83f348105 (diff) | |
download | erlang-a5109ba45402d9cd215ea3d3f56c4a2c488d6593.tar.gz |
Merge branch 'sverker/crypto/unload-mutex-leak/OTP-17668' into maint-24
* sverker/crypto/unload-mutex-leak/OTP-17668:
crypto: Make get_curve_cnt() less racy
crypto: Fix mutex memory leak at unload
-rw-r--r-- | lib/crypto/c_src/algorithms.c | 35 | ||||
-rw-r--r-- | lib/crypto/c_src/algorithms.h | 1 | ||||
-rw-r--r-- | lib/crypto/c_src/crypto.c | 3 |
3 files changed, 18 insertions, 21 deletions
diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c index aaad836869..2c73b2005c 100644 --- a/lib/crypto/c_src/algorithms.c +++ b/lib/crypto/c_src/algorithms.c @@ -53,8 +53,6 @@ void init_algorithms_types(ErlNifEnv* env) /* ciphers and macs are initiated statically */ } -void cleanup_algorithms_types(ErlNifEnv* env); - void cleanup_algorithms_types(ErlNifEnv* env) { enif_mutex_destroy(mtx_init_curve_types); @@ -207,44 +205,36 @@ ERL_NIF_TERM curve_algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ return enif_make_list_from_array(env, algo_curve[fips_mode], algo_curve_cnt); } -#if defined(HAVE_EC) int init_curves(ErlNifEnv* env, int fips); +#if defined(HAVE_EC) int valid_curve(int nid); #endif int get_curve_cnt(ErlNifEnv* env, int fips) { - static unsigned int algo_curve_cnt, algo_curve_cnt_initialized; - static unsigned int algo_curve_fips_cnt, algo_curve_fips_cnt_initialized; + static int algo_curve_cnt = -1; + static int algo_curve_fips_cnt = -1; int cnt = 0; - if (0 == fips && 1 == algo_curve_cnt_initialized) { + if (0 == fips && algo_curve_cnt >= 0) { return algo_curve_cnt; } - if (1 == fips && 1 == algo_curve_fips_cnt_initialized) { + if (1 == fips && algo_curve_fips_cnt >= 0) { return algo_curve_fips_cnt; } enif_mutex_lock(mtx_init_curve_types); if (1 == fips) { - if (1 == algo_curve_fips_cnt_initialized) { + if (algo_curve_fips_cnt >= 0) { return algo_curve_fips_cnt; } - -#if defined(HAVE_EC) algo_curve_fips_cnt = init_curves(env, 1); -#endif /* defined(HAVE_EC) */ cnt = algo_curve_fips_cnt; - algo_curve_fips_cnt_initialized = 1; } else { - if (1 == algo_curve_cnt_initialized) { + if (algo_curve_cnt >= 0) { return algo_curve_cnt; } - -#if defined(HAVE_EC) algo_curve_cnt = init_curves(env, 0); -#endif /* defined(HAVE_EC) */ - cnt = algo_curve_cnt ; - algo_curve_cnt_initialized = 1; + cnt = algo_curve_cnt; } enif_mutex_unlock(mtx_init_curve_types); @@ -270,12 +260,12 @@ void init_curve_types(ErlNifEnv* env) { #endif /* defined(HAVE_EC) */ - ASSERT(curve_cnt <= sizeof(algo_curve)/sizeof(ERL_NIF_TERM)); + ASSERT(curve_cnt <= sizeof(algo_curve[0])/sizeof(ERL_NIF_TERM)); } -#if defined(HAVE_EC) int init_curves(ErlNifEnv* env, int fips) { +#if defined(HAVE_EC) int cnt = 0; #ifdef NID_secp160k1 @@ -624,8 +614,13 @@ int init_curves(ErlNifEnv* env, int fips) { } return cnt; +#else /* if not HAVE_EC */ + return 0; +#endif } +#if defined(HAVE_EC) + /* Check if the curve in nid is supported by the current cryptolib and current FIPS state. */ diff --git a/lib/crypto/c_src/algorithms.h b/lib/crypto/c_src/algorithms.h index 60feefa482..dca6a5d7ce 100644 --- a/lib/crypto/c_src/algorithms.h +++ b/lib/crypto/c_src/algorithms.h @@ -24,6 +24,7 @@ #include "common.h" 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 a79bd12fca..66239462be 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -300,5 +300,6 @@ static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, static void unload(ErlNifEnv* env, void* priv_data) { - --library_refc; + if (--library_refc == 0) + cleanup_algorithms_types(env); } |