File 0651-Fixing-core-dump-caused-by-enable-disable-FIPS.patch of Package erlang

From acdbd98ecb8fd780c1a8f15d426e7cdaa48d8940 Mon Sep 17 00:00:00 2001
From: graorane <35835878+graorane@users.noreply.github.com>
Date: Tue, 17 Aug 2021 16:50:55 +0530
Subject: [PATCH 1/2] Fixing core dump caused by enable/disable FIPS

FIPS enable and disable or vice versa just to check curve count, sometime leads to core dump at the time of process exit.  So this fix  avoids enable/disable FIPS.  It delays getting curve count during FIPS mode. Simultaneously it keeps the optimization added to cache of supported curves in the NIF at application
---
 lib/crypto/c_src/algorithms.c | 76 +++++++++++++++++++++++++++--------
 1 file changed, 59 insertions(+), 17 deletions(-)

diff --git a/lib/crypto/c_src/algorithms.c b/lib/crypto/c_src/algorithms.c
index f78fcd778b..51c5901929 100644
--- a/lib/crypto/c_src/algorithms.c
+++ b/lib/crypto/c_src/algorithms.c
@@ -31,9 +31,10 @@ static unsigned int algo_pubkey_cnt, algo_pubkey_fips_cnt;
 static ERL_NIF_TERM algo_pubkey[12]; /* increase when extending the list */
 void init_pubkey_types(ErlNifEnv* env);
 
-static unsigned int algo_curve_cnt, algo_curve_fips_cnt;
 static ERL_NIF_TERM algo_curve[2][89]; /* increase when extending the list */
+static ErlNifMutex* mtx_init_curve_types;
 void init_curve_types(ErlNifEnv* env);
+int get_curve_cnt(ErlNifEnv* env, int fips);
 
 static unsigned int algo_rsa_opts_cnt, algo_rsa_opts_fips_cnt;
 static ERL_NIF_TERM algo_rsa_opts[11]; /* increase when extending the list */
@@ -44,6 +45,7 @@ void init_rsa_opts_types(ErlNifEnv* env);
 
 void init_algorithms_types(ErlNifEnv* env)
 {
+    mtx_init_curve_types =  enif_mutex_create("init_curve_types");
     init_hash_types(env);
     init_pubkey_types(env);
     init_curve_types(env);
@@ -51,7 +53,10 @@ void init_algorithms_types(ErlNifEnv* env)
     /* ciphers and macs are initiated statically */
 }
 
-
+void cleanup_algorithms_types(ErlNifEnv* env)
+{
+    enif_mutex_destroy(mtx_init_curve_types);
+}
 
 /*================================================================
   Hash algorithms
@@ -190,12 +195,14 @@ ERL_NIF_TERM mac_algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 
 ERL_NIF_TERM curve_algorithms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {
+    int fips_mode = 0;
+    int algo_curve_cnt = 0;
+
 #ifdef FIPS_SUPPORT
-    if (FIPS_mode())
-        return enif_make_list_from_array(env, algo_curve[1], algo_curve_fips_cnt);
-    else
+    fips_mode = FIPS_mode();
 #endif
-    return enif_make_list_from_array(env, algo_curve[0], algo_curve_cnt);
+    algo_curve_cnt = get_curve_cnt(env, fips_mode);
+    return enif_make_list_from_array(env, algo_curve[fips_mode], algo_curve_cnt);
 }
 
 #if defined(HAVE_EC)
@@ -203,30 +210,64 @@ int init_curves(ErlNifEnv* env, int fips);
 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;
+    int cnt = 0;
+    if (0 == fips  && 1 == algo_curve_cnt_initialized) {
+        return algo_curve_cnt;
+    }
+
+    if (1 == fips  && 1 == algo_curve_fips_cnt_initialized) {
+        return algo_curve_fips_cnt;
+    }
+
+    enif_mutex_lock(mtx_init_curve_types);
+    if (1 == fips) {
+        if (1 == algo_curve_fips_cnt_initialized) {
+            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) {
+            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;
+    }
+    enif_mutex_unlock(mtx_init_curve_types);
+
+    return cnt;
+}
+
 void init_curve_types(ErlNifEnv* env) {
-    algo_curve_cnt = algo_curve_fips_cnt = 0;
+    int curve_cnt = 0;
 #if defined(HAVE_EC)
+
 #ifdef FIPS_SUPPORT
     if (FIPS_mode()) {
         // enabled
-        algo_curve_fips_cnt = init_curves(env, 1);
-        FIPS_mode_set(0); // disable
-        algo_curve_cnt = init_curves(env, 0);
-        FIPS_mode_set(1); // re-enable
+        curve_cnt = get_curve_cnt(env, 1);
     } else {
         // disabled
-        algo_curve_cnt = init_curves(env, 0);
-        FIPS_mode_set(1); // enable
-        algo_curve_fips_cnt = init_curves(env, 1);
-        FIPS_mode_set(0); // re-disable
+        curve_cnt = get_curve_cnt(env, 0);
     }
 #else
     // No fips support
-    algo_curve_cnt = algo_curve_fips_cnt = init_curves(env, 0);
+    curve_cnt = get_curve_cnt(env, 0);
 #endif   
 #endif /* defined(HAVE_EC) */
 
-    ASSERT(algo_curve_cnt+algo_curve_fips_cnt <= sizeof(algo_curve)/sizeof(ERL_NIF_TERM));
+    ASSERT(curve_cnt <= sizeof(algo_curve)/sizeof(ERL_NIF_TERM));
 }
 
 
@@ -685,3 +726,4 @@ void init_rsa_opts_types(ErlNifEnv* env) {
     ASSERT(algo_rsa_opts_cnt <= sizeof(algo_rsa_opts)/sizeof(ERL_NIF_TERM));
 }
 
+
-- 
2.31.1

openSUSE Build Service is sponsored by