In PKINIT, use library initializer for OpenSSL
authorTomas Kuthan <tkuthan@gmail.com>
Fri, 11 Apr 2014 13:36:53 +0000 (15:36 +0200)
committerGreg Hudson <ghudson@mit.edu>
Tue, 15 Apr 2014 16:21:13 +0000 (12:21 -0400)
Use a library initializer to prevent multiple threads using PKINIT
from concurently initializing OpenSSL functions.  For cases where
MT-safety is not assured by registering OpenSSL locking callbacks,
this significantly lowers the odds of crashes caused by races in
OpenSSL initialization.  (If OpenSSL initialization functions are
called by some other thread directly, crashes are still possible.)

[ghudson@mit.edu: simplify code changes and commit message]

ticket: 6413

src/plugins/preauth/pkinit/pkinit_crypto_openssl.c

index 02378134f08068bd0853643239f9c6d577544ed6..6133f093e233d10b9fe148a555346fac52fa6286 100644 (file)
@@ -43,8 +43,6 @@
 
 #include "pkinit_crypto_openssl.h"
 
-static void openssl_init(void);
-
 static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
 static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
 
@@ -423,14 +421,15 @@ unsigned char pkinit_4096_dhprime[4096/8] = {
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
+MAKE_INIT_FUNCTION(pkinit_openssl_init);
+
 krb5_error_code
 pkinit_init_plg_crypto(pkinit_plg_crypto_context *cryptoctx)
 {
     krb5_error_code retval = ENOMEM;
     pkinit_plg_crypto_context ctx = NULL;
 
-    /* initialize openssl routines */
-    openssl_init();
+    (void)CALL_INIT_FUNCTION(pkinit_openssl_init);
 
     ctx = malloc(sizeof(*ctx));
     if (ctx == NULL)
@@ -2921,18 +2920,14 @@ cleanup:
     return retval;
 }
 
-static void
-openssl_init()
+int
+pkinit_openssl_init()
 {
-    static int did_init = 0;
-
-    if (!did_init) {
-        /* initialize openssl routines */
-        CRYPTO_malloc_init();
-        ERR_load_crypto_strings();
-        OpenSSL_add_all_algorithms();
-        did_init++;
-    }
+    /* Initialize OpenSSL. */
+    CRYPTO_malloc_init();
+    ERR_load_crypto_strings();
+    OpenSSL_add_all_algorithms();
+    return 0;
 }
 
 static krb5_error_code