2582N/A#
2582N/A# This file adds the code to setup internal mutexes and callback function.
4006N/A# PSARC/2014/077
4459N/A# PSARC/2015/043
2582N/A# This change was implemented in-house. The issue was brought up to
2582N/A# the upstream engineers, but there was no commitment.
2582N/A#
7161N/A--- a/crypto/cryptlib.c 2016-05-03 06:44:42.000000000 -0700
7161N/A+++ b/crypto/cryptlib.c 2016-09-02 08:47:23.640202700 -0700
2582N/A@@ -116,6 +116,7 @@
2582N/A
2582N/A #include "cryptlib.h"
2582N/A #include <openssl/safestack.h>
2582N/A+#include <pthread.h>
2582N/A
2582N/A #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
4006N/A static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
4006N/A@@ -184,6 +185,8 @@
4006N/A */
4006N/A static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
2582N/A
2582N/A+static pthread_mutex_t *solaris_openssl_locks;
4006N/A+
4006N/A static void (MS_FAR *locking_callback) (int mode, int type,
4006N/A const char *file, int line) = 0;
4006N/A static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
4459N/A@@ -373,7 +376,10 @@
4459N/A void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
4459N/A (const char *file, int line))
4459N/A {
4459N/A- dynlock_create_callback = func;
4459N/A+ /*
4459N/A+ * we now setup our own dynamic locking callback, and disallow
4459N/A+ * setting of another locking callback.
4459N/A+ */
4459N/A }
7161N/A
4459N/A void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
4459N/A@@ -382,7 +388,10 @@
4459N/A const char *file,
4459N/A int line))
4459N/A {
4459N/A- dynlock_lock_callback = func;
4459N/A+ /*
4459N/A+ * we now setup our own dynamic locking callback, and disallow
4459N/A+ * setting of another locking callback.
4459N/A+ */
4459N/A }
7161N/A
4459N/A void CRYPTO_set_dynlock_destroy_callback(void (*func)
4459N/A@@ -389,7 +398,10 @@
4459N/A (struct CRYPTO_dynlock_value *l,
4459N/A const char *file, int line))
4459N/A {
4459N/A- dynlock_destroy_callback = func;
4459N/A+ /*
4459N/A+ * we now setup our own dynamic locking callback, and disallow
4459N/A+ * setting of another locking callback.
4459N/A+ */
4459N/A }
7161N/A
4459N/A void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
7161N/A@@ -402,6 +414,127 @@
4006N/A return (add_lock_callback);
4006N/A }
7161N/A
2582N/A+/*
2582N/A+ * This is the locking callback function which all applications will be
2582N/A+ * using when CRYPTO_lock() is called.
2582N/A+ */
2582N/A+static void solaris_locking_callback(int mode, int type, const char *file,
2582N/A+ int line)
4459N/A+{
4459N/A+ if (mode & CRYPTO_LOCK) {
7161N/A+ (void) pthread_mutex_lock(&solaris_openssl_locks[type]);
4459N/A+ } else {
7161N/A+ (void) pthread_mutex_unlock(&solaris_openssl_locks[type]);
4459N/A+ }
4459N/A+}
4459N/A+
4459N/A+/*
4459N/A+ * Implement Solaris's own dynamic locking routines.
4459N/A+ */
4459N/A+static struct CRYPTO_dynlock_value *
4459N/A+solaris_dynlock_create(const char *file, int line)
4459N/A+{
4459N/A+ int ret;
4459N/A+ pthread_mutex_t *dynlock;
4459N/A+
4459N/A+ dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
4459N/A+ if (dynlock == NULL) {
4459N/A+ return (NULL);
4459N/A+ }
4459N/A+
4459N/A+ ret = pthread_mutex_init(dynlock, NULL);
7161N/A+ OPENSSL_assert(ret == 0);
4459N/A+
4459N/A+ return ((struct CRYPTO_dynlock_value *)dynlock);
4459N/A+}
4459N/A+
4459N/A+static void
4459N/A+solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
4459N/A+ const char *file, int line)
4459N/A+{
4459N/A+ int ret;
4459N/A+
4459N/A+ if (mode & CRYPTO_LOCK) {
4459N/A+ ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
4459N/A+ } else {
4459N/A+ ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
4459N/A+ }
4459N/A+
4459N/A+ OPENSSL_assert(ret == 0);
4459N/A+}
4459N/A+
4459N/A+static void
4459N/A+solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
4459N/A+ const char *file, int line)
4459N/A+{
4459N/A+ int ret;
4459N/A+ ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
7161N/A+ OPENSSL_assert(ret == 0);
4459N/A+}
2582N/A+
2582N/A+
7161N/A+static void solaris_fork_prep(void)
7161N/A+{
7161N/A+ int i;
7161N/A+
7161N/A+ for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
7161N/A+ (void) pthread_mutex_lock(&solaris_openssl_locks[i]);
7161N/A+ }
7161N/A+}
7161N/A+
7161N/A+static void solaris_fork_post(void)
4459N/A+{
7161N/A+ int i;
7161N/A+
7161N/A+ for (i = CRYPTO_NUM_LOCKS - 1; i >= 0; i--) {
7161N/A+ (void) pthread_mutex_unlock(&solaris_openssl_locks[i]);
7161N/A+ }
7161N/A+
7161N/A+ OPENSSL_assert(dynlock_create_callback == solaris_dynlock_create);
7161N/A+ OPENSSL_assert(dynlock_lock_callback == solaris_dynlock_lock);
7161N/A+ OPENSSL_assert(dynlock_destroy_callback == solaris_dynlock_destroy);
7161N/A+ OPENSSL_assert(locking_callback == solaris_locking_callback);
4459N/A+}
2582N/A+
2582N/A+/*
7161N/A+ * This is called by the _init() function to setup locks used by OpenSSL
7161N/A+ * and locking callback functions.
2582N/A+ */
7161N/A+void
7161N/A+solaris_locking_setup()
4459N/A+{
4459N/A+ int i;
2582N/A+
4459N/A+ /* setup the dynlock callback if not already */
4459N/A+ if (dynlock_create_callback == NULL) {
4459N/A+ dynlock_create_callback = solaris_dynlock_create;
4459N/A+ }
4459N/A+ if (dynlock_lock_callback == NULL) {
4459N/A+ dynlock_lock_callback = solaris_dynlock_lock;
4459N/A+ }
4459N/A+ if (dynlock_destroy_callback == NULL) {
4459N/A+ dynlock_destroy_callback = solaris_dynlock_destroy;
4459N/A+ }
7161N/A+ if (locking_callback == NULL) {
7161N/A+ locking_callback = solaris_locking_callback;
4459N/A+ }
2582N/A+
7161N/A+ /* allocate and initialize locks needed by OpenSSL */
4459N/A+ solaris_openssl_locks =
7161N/A+ OPENSSL_malloc(sizeof (pthread_mutex_t) * CRYPTO_NUM_LOCKS);
4459N/A+ if (solaris_openssl_locks == NULL) {
4459N/A+ fprintf(stderr,
4459N/A+ "solaris_locking_setup: memory allocation failure.\n");
4459N/A+ abort();
4459N/A+ }
7161N/A+ for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
7161N/A+ (void) pthread_mutex_init(&solaris_openssl_locks[i], NULL);
7161N/A+ }
4459N/A+
7161N/A+ (void) pthread_atfork(solaris_fork_prep, solaris_fork_post, solaris_fork_post);
7161N/A+}
2582N/A+
2582N/A+
4006N/A void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
4006N/A const char *file, int line))
4006N/A {
7161N/A@@ -410,7 +541,11 @@
4006N/A * started.
4006N/A */
4006N/A OPENSSL_init();
4006N/A- locking_callback = func;
2582N/A+
4459N/A+ /*
4459N/A+ * we now setup our own locking callback and mutexes, and disallow
4459N/A+ * setting of another locking callback.
4459N/A+ */
4006N/A }
2582N/A
4006N/A void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
7161N/A@@ -471,9 +606,10 @@
4459N/A
4459N/A int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
4459N/A {
4459N/A- if (threadid_callback)
4459N/A- return 0;
4459N/A- threadid_callback = func;
4459N/A+ /*
4459N/A+ * Use the backup method (the address of 'errno') to identify the
4459N/A+ * thread and disallow setting the threadid callback.
4459N/A+ */
4459N/A return 1;
4459N/A }
4459N/A
7161N/A@@ -529,7 +665,10 @@
4459N/A
4459N/A void CRYPTO_set_id_callback(unsigned long (*func) (void))
4459N/A {
4459N/A- id_callback = func;
4459N/A+ /*
4459N/A+ * Use the backup method to identify the thread/process.
4459N/A+ * Setting the id callback is disallowed.
4459N/A+ */
4459N/A }
4459N/A
4459N/A unsigned long CRYPTO_thread_id(void)
2582N/A--- openssl-1.0.1f/crypto/cryptlib.h.~1~ Fri Feb 7 10:41:42 2014
2582N/A+++ openssl-1.0.1f/crypto/cryptlib.h Thu Feb 6 16:04:16 2014
2582N/A@@ -104,6 +104,8 @@
2582N/A void *OPENSSL_stderr(void);
2582N/A extern int OPENSSL_NONPIC_relocated;
2582N/A
2582N/A+void solaris_locking_setup();
2582N/A+
2582N/A #ifdef __cplusplus
2582N/A }
2582N/A #endif
2582N/A--- openssl-1.0.1f/crypto/sparccpuid.S.~1~ Fri Feb 7 10:41:37 2014
2582N/A+++ openssl-1.0.1f/crypto/sparccpuid.S Thu Feb 6 16:04:14 2014
7161N/A@@ -525,5 +525,7 @@
7161N/A .size _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
2582N/A
2582N/A .section ".init",#alloc,#execinstr
2582N/A+ call solaris_locking_setup
2582N/A+ nop
2582N/A call OPENSSL_cpuid_setup
2582N/A nop
2582N/A--- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~ Wed Feb 12 13:20:09 2014
2582N/A+++ openssl-1.0.1f/crypto/x86_64cpuid.pl Wed Feb 12 13:21:20 2014
2582N/A@@ -20,7 +20,10 @@
2582N/A print<<___;
2582N/A .extern OPENSSL_cpuid_setup
2582N/A .hidden OPENSSL_cpuid_setup
2582N/A+.extern solaris_locking_setup
2582N/A+.hidden solaris_locking_setup
2582N/A .section .init
2582N/A+ call solaris_locking_setup
2582N/A call OPENSSL_cpuid_setup
2582N/A
2582N/A .hidden OPENSSL_ia32cap_P
2582N/A--- openssl-1.0.1f/crypto/x86cpuid.pl.~1~ Wed Feb 12 13:38:03 2014
2582N/A+++ openssl-1.0.1f/crypto/x86cpuid.pl Wed Feb 12 13:38:31 2014
7161N/A@@ -379,8 +379,10 @@
2582N/A &ret ();
7161N/A &function_end_B("OPENSSL_ia32_rdseed");
2582N/A
2582N/A+&initseg("solaris_locking_setup");
2582N/A &initseg("OPENSSL_cpuid_setup");
2582N/A
7161N/A+&hidden("solaris_locking_setup");
7161N/A &hidden("OPENSSL_cpuid_setup");
7161N/A &hidden("OPENSSL_ia32cap_P");
7161N/A