changeset 10626:9c09f5dd637e

6881623 CRYPTO_num_locks() should be used instead of CRYPTO_NUM_LOCKS
author Paul Wernau <Paul.Wernau@Sun.COM>
date Wed, 23 Sep 2009 18:41:35 -0400
parents 76705885a9bb
children e56a44d6d742
files usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c usr/src/lib/libipsecutil/common/ipsec_util.h
diffstat 2 files changed, 87 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c	Wed Sep 23 18:26:43 2009 -0400
+++ b/usr/src/lib/libipsecutil/common/ipsec_libssl_setup.c	Wed Sep 23 18:41:35 2009 -0400
@@ -57,17 +57,15 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 /*
  * Thread setup portions of this code derived from
- * OpenSSL 0.9.4 file mt/mttest.c examples
+ * OpenSSL 0.9.x file mt/mttest.c examples
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -92,16 +90,22 @@
 static void (*CRYPTO_set_locking_callback_fn)() = NULL;
 static void (*CRYPTO_set_id_callback_fn)() = NULL;
 static void (*X509_NAME_free_fn)() = NULL;
+static int (*CRYPTO_num_locks_fn)() = NULL;
+static void *(*OPENSSL_malloc_fn)() = NULL;
+static void (*OPENSSL_free_fn)() = NULL;
 
 static void solaris_locking_callback(int, int, char *, int);
 static unsigned long solaris_thread_id(void);
-static void thread_setup(void);
+static boolean_t thread_setup(void);
 /* LINTED E_STATIC_UNUSED */
 static void thread_cleanup(void);
 
 mutex_t init_lock = DEFAULTMUTEX;
-static mutex_t lock_cs[CRYPTO_NUM_LOCKS];
-static long lock_count[CRYPTO_NUM_LOCKS];
+static mutex_t *lock_cs;
+static long *lock_count;
+
+static boolean_t libssl_loaded = B_FALSE;
+static boolean_t libcrypto_loaded = B_FALSE;
 
 void
 libssl_load()
@@ -161,7 +165,8 @@
 		if (X509_NAME_free_fn == NULL)
 			goto libssl_err;
 
-		thread_setup();
+		if (thread_setup() == B_FALSE)
+			goto libssl_err;
 
 		libssl_loaded = B_TRUE;
 	}
@@ -172,18 +177,75 @@
 	(void) mutex_unlock(&init_lock);
 }
 
-static void
+void
+libcrypto_load()
+{
+	void *dldesc;
+
+	(void) mutex_lock(&init_lock);
+	if (libcrypto_loaded) {
+		(void) mutex_unlock(&init_lock);
+		return;
+	}
+
+	dldesc = dlopen(LIBCRYPTO, RTLD_LAZY);
+	if (dldesc != NULL) {
+		CRYPTO_num_locks_fn = (int(*)())dlsym(dldesc,
+		    "CRYPTO_num_locks");
+		if (CRYPTO_num_locks_fn == NULL)
+			goto libcrypto_err;
+
+		/*
+		 * OPENSSL_free is really a macro, so we
+		 * need to reference the actual symbol,
+		 * which is CRYPTO_free.
+		 */
+		OPENSSL_free_fn = (void(*)())dlsym(dldesc,
+		    "CRYPTO_free");
+		if (OPENSSL_free_fn == NULL)
+			goto libcrypto_err;
+
+		/*
+		 * OPENSSL_malloc is really a macro, so we
+		 * need to reference the actual symbol,
+		 * which is CRYPTO_malloc.
+		 */
+		OPENSSL_malloc_fn = (void *(*)())dlsym(dldesc,
+		    "CRYPTO_malloc");
+		if (OPENSSL_malloc_fn == NULL)
+			goto libcrypto_err;
+
+		libcrypto_loaded = B_TRUE;
+	}
+	(void) mutex_unlock(&init_lock);
+	return;
+libcrypto_err:
+	(void) dlclose(dldesc);
+	(void) mutex_unlock(&init_lock);
+}
+
+static boolean_t
 thread_setup(void)
 {
 	int i;
 
-	for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
+	if ((lock_cs = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() *
+	    sizeof (mutex_t))) == NULL)
+		return (B_FALSE);
+	if ((lock_count = OPENSSL_malloc_fn(CRYPTO_num_locks_fn() *
+	    sizeof (long))) == NULL) {
+		OPENSSL_free_fn(lock_cs);
+		return (B_FALSE);
+	}
+
+	for (i = 0; i < CRYPTO_num_locks_fn(); i++) {
 		lock_count[i] = 0;
 		(void) mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL);
 	}
 
 	CRYPTO_set_id_callback_fn((unsigned long (*)())solaris_thread_id);
 	CRYPTO_set_locking_callback_fn((void (*)())solaris_locking_callback);
+	return (B_TRUE);
 }
 
 static void
@@ -194,8 +256,10 @@
 	(void) mutex_lock(&init_lock);
 	CRYPTO_set_locking_callback_fn(NULL);
 	CRYPTO_set_id_callback_fn(NULL);
-	for (i = 0; i < CRYPTO_NUM_LOCKS; i++)
+	for (i = 0; i < CRYPTO_num_locks_fn(); i++)
 		(void) mutex_destroy(&(lock_cs[i]));
+	OPENSSL_free_fn(lock_cs);
+	OPENSSL_free_fn(lock_count);
 	(void) mutex_unlock(&init_lock);
 }
 
@@ -223,9 +287,11 @@
 void
 print_asn1_name(FILE *file, const unsigned char *buf, long buflen)
 {
-	libssl_load();
+	libcrypto_load();
+	if (libcrypto_loaded)
+		libssl_load();
 
-	if (libssl_loaded) {
+	if (libssl_loaded && libcrypto_loaded) {
 		X509_NAME *x509name = NULL;
 		const unsigned char *p;
 
--- a/usr/src/lib/libipsecutil/common/ipsec_util.h	Wed Sep 23 18:26:43 2009 -0400
+++ b/usr/src/lib/libipsecutil/common/ipsec_util.h	Wed Sep 23 18:41:35 2009 -0400
@@ -196,12 +196,18 @@
 extern int parsedbgopts(char *);
 
 /*
- * OpenSSL library
+ * SSL library (OpenSSL)
  */
 #define	LIBSSL	"libssl.so"
 
 void libssl_load(void);
-boolean_t libssl_loaded;
+
+/*
+ * crypto library (OpenSSL)
+ */
+#define	LIBCRYPTO	"libcrypto.so"
+
+void libcrypto_load(void);
 
 /*
  * functions to manipulate the kmcookie-label mapping file