--- old/usr/src/lib/libcryptoutil/common/cryptoutil.h	Thu Jun  5 21:16:33 2014
+++ new/usr/src/lib/libcryptoutil/common/cryptoutil.h	Thu Jun  5 21:16:33 2014
@@ -22,6 +22,7 @@
  */
 /*
  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #ifndef _CRYPTOUTIL_H
@@ -216,9 +217,6 @@
 extern int pkcs11_get_random(void *dbuf, size_t dlen);
 extern int pkcs11_get_urandom(void *dbuf, size_t dlen);
 extern int pkcs11_get_nzero_urandom(void *dbuf, size_t dlen);
-extern void pkcs11_close_random(void);
-extern void pkcs11_close_urandom(void);
-extern void pkcs11_close_urandom_seed(void);
 extern int pkcs11_read_data(char *filename, void **dbuf, size_t *dlen);
 
 extern int open_nointr(const char *path, int oflag, ...);
--- old/usr/src/lib/libcryptoutil/common/mapfile-vers	Thu Jun  5 21:16:34 2014
+++ new/usr/src/lib/libcryptoutil/common/mapfile-vers	Thu Jun  5 21:16:34 2014
@@ -19,6 +19,7 @@
 # CDDL HEADER END
 #
 # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2014, OmniTI Computer Consulting Inc. All rights reserved.
 #
 
 #
@@ -54,9 +55,6 @@
 	get_pkcs11conf_info;
 	hexstr_to_bytes;
 	open_nointr;
-	pkcs11_close_random;
-	pkcs11_close_urandom;
-	pkcs11_close_urandom_seed;
 	pkcs11_default_token;
 	pkcs11_free_uri;
 	pkcs11_get_nzero_urandom;
--- old/usr/src/lib/libcryptoutil/common/random.c	Thu Jun  5 21:16:34 2014
+++ new/usr/src/lib/libcryptoutil/common/random.c	Thu Jun  5 21:16:34 2014
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <stdio.h>
@@ -33,6 +34,7 @@
 #include <cryptoutil.h>
 #include <pthread.h>
 
+#pragma init(pkcs11_random_init)
 
 static pthread_mutex_t	random_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t	urandom_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -181,13 +183,13 @@
 	(void) pthread_mutex_unlock(mtx);
 }
 
-void
+static void
 pkcs11_close_random(void)
 {
 	pkcs11_close_common(&random_fd, &random_mutex);
 }
 
-void
+static void
 pkcs11_close_urandom(void)
 {
 	pkcs11_close_common(&urandom_fd, &urandom_mutex);
@@ -199,7 +201,7 @@
 	pkcs11_close_common(&random_seed_fd, &random_seed_mutex);
 }
 
-void
+static void
 pkcs11_close_urandom_seed(void)
 {
 	pkcs11_close_common(&urandom_seed_fd, &urandom_seed_mutex);
@@ -376,4 +378,46 @@
 		((char *)dbuf)[i] = extrarand[bytesleft];
 	}
 	return (0);
+}
+
+static void
+pkcs11_random_prepare(void)
+{
+	/*
+	 * NOTE - None of these are acquired more than one at a time.
+	 * I can therefore acquire all four without fear of deadlock.
+	 */
+	(void) pthread_mutex_lock(&random_mutex);
+	(void) pthread_mutex_lock(&urandom_mutex);
+	(void) pthread_mutex_lock(&random_seed_mutex);
+	(void) pthread_mutex_lock(&urandom_seed_mutex);
+}
+
+static void
+pkcs11_random_parent_post(void)
+{
+	/* Drop the mutexes and get back to work! */
+	(void) pthread_mutex_unlock(&urandom_seed_mutex);
+	(void) pthread_mutex_unlock(&random_seed_mutex);
+	(void) pthread_mutex_unlock(&urandom_mutex);
+	(void) pthread_mutex_unlock(&random_mutex);
+}
+
+static void
+pkcs11_random_child_post(void)
+{
+	pkcs11_random_parent_post();
+
+	/* Also, close the FDs, just in case. */
+	pkcs11_close_random();
+	pkcs11_close_urandom();
+	pkcs11_close_random_seed();
+	pkcs11_close_urandom_seed();
+}
+
+static void
+pkcs11_random_init(void)
+{
+	(void) pthread_atfork(pkcs11_random_prepare, pkcs11_random_parent_post,
+	    pkcs11_random_child_post);
 }
--- old/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c	Thu Jun  5 21:16:34 2014
+++ new/usr/src/lib/pkcs11/libpkcs11/common/metaGeneral.c	Thu Jun  5 21:16:34 2014
@@ -21,8 +21,9 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  */
-
 /*
  * General-Purpose Functions
  * (as defined in PKCS#11 spec section 11.4)
@@ -196,8 +197,12 @@
 
 	(void) pthread_mutex_lock(&initmutex);
 
-	pkcs11_close_urandom();
-	pkcs11_close_urandom_seed();
+	/*
+	 * There used to be calls to cleanup libcryptoutil here.  Given that
+	 * libcryptoutil can be linked and invoked independently of PKCS#11,
+	 * cleaning up libcryptoutil here makes no sense.  Decoupling these
+	 * two also prevent deadlocks and other artificial dependencies.
+	 */
 
 	meta_objectManager_finalize();
 
--- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c	Thu Jun  5 21:16:34 2014
+++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c	Thu Jun  5 21:16:34 2014
@@ -21,6 +21,8 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <strings.h>
@@ -354,9 +356,12 @@
 	softtoken_initialized = B_FALSE;
 	softtoken_pid = 0;
 
-	pkcs11_close_urandom();
-	pkcs11_close_urandom_seed();
-	pkcs11_close_random();
+	/*
+	 * There used to be calls to cleanup libcryptoutil here.  Given that
+	 * libcryptoutil can be linked and invoked independently of PKCS#11,
+	 * cleaning up libcryptoutil here makes no sense.  Decoupling these
+	 * two also prevent deadlocks and other artificial dependencies.
+	 */
 
 	/* Destroy the session list lock here */
 	(void) pthread_mutex_destroy(&soft_sessionlist_mutex);
