File 1361-crypto-Remove-unsafe-OpenSSL-cleanup.patch of Package erlang
From a98fab6ea9007cbce89606a63dff4653a5e44882 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 7 Aug 2025 17:41:05 +0200
Subject: [PATCH] crypto: Remove unsafe OpenSSL cleanup
Seen symptom:
crypto:strong_rand_bytes() failing with 'low_entropy' after
init:restart on MacOS with statically linked OpenSSL.
Caused by the cleanup done in unload() followed by dlclose() not
actually unloading the lib (because reasons). When loaded again after
init:restart(), crypto.so had intact static data in some inconsistent
state.
---
lib/crypto/c_src/crypto.c | 21 ++++++++++-----------
lib/crypto/c_src/mac.c | 14 --------------
lib/crypto/c_src/mac.h | 1 -
3 files changed, 10 insertions(+), 26 deletions(-)
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index af493a2cdb..ee00d15c34 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -394,17 +394,16 @@ static void unload(ErlNifEnv* env, void* priv_data)
destroy_curve_mutex();
destroy_engine_mutex(env);
-#ifdef HAS_3_0_API
- fini_mac_types();
-# ifdef FIPS_SUPPORT
- if (fips_provider) {
- OSSL_PROVIDER_unload(fips_provider);
- }
-# endif
- while (prov_cnt > 0) {
- OSSL_PROVIDER_unload(prov[--prov_cnt]);
- }
-#endif
+ /*
+ * We do not do any OpenSSL cleanup here as we are not sure the lib
+ * will actually be unloaded. For example
+ * + With musl libc, dlclose() is a no-op.
+ * + On MacOS with statically linked OpenSSL crypto.so has been seen to
+ * be locked in place after OSSL_provider_load() has been called.
+ *
+ * So, we rely on OpenSSL doing automatic cleanup with its own "atexit"
+ * handler if the lib is actually unloaded.
+ */
}
}
diff --git a/lib/crypto/c_src/mac.c b/lib/crypto/c_src/mac.c
index 3d1f0cf9b4..3db57da491 100644
--- a/lib/crypto/c_src/mac.c
+++ b/lib/crypto/c_src/mac.c
@@ -136,20 +136,6 @@ void init_mac_types(ErlNifEnv* env)
p->name.atom = atom_false; /* end marker */
}
-void fini_mac_types(void)
-{
-#if defined(HAS_3_0_API)
- struct mac_type_t* p = mac_types;
-
- for (p = mac_types; p->name.atom != atom_false; p++) {
- EVP_MAC_free(p->evp_mac);
- p->evp_mac = NULL;
- }
-#endif
-}
-
-
-
ERL_NIF_TERM mac_types_as_list(ErlNifEnv* env)
{
struct mac_type_t* p;
diff --git a/lib/crypto/c_src/mac.h b/lib/crypto/c_src/mac.h
index 937a80d132..60cb4ff1d9 100644
--- a/lib/crypto/c_src/mac.h
+++ b/lib/crypto/c_src/mac.h
@@ -28,7 +28,6 @@
int init_mac_ctx(ErlNifEnv *env, ErlNifBinary* rt_buf);
void init_mac_types(ErlNifEnv* env);
-void fini_mac_types(void);
ERL_NIF_TERM mac_types_as_list(ErlNifEnv* env);
--
2.43.0