On Monday,  3 August 2015, at  9.24 am EDT, Benjamin Barenblat wrote:
> Last night, I realized one of the FFI libraries I’ve written assumes a
> thread-safe OpenSSL.  This is currently not the case, as I’ve noted in
> bug #206 […].

Here’s a patch to fix this; I’ve also uploaded it to the bugtracker.
Code review is most appreciated.

For auditability, the patch’s SHA256 is
f5bcd42c3210f55a173a7ebd88434d12c679725774240d13c5bad7b835f41ce1.

Thanks in advance,
Benjamin
# HG changeset patch
# User Benjamin Barenblat <[email protected]>
# Date 1438870553 14400
#      Thu Aug 06 10:15:53 2015 -0400
# Node ID 52bc5143c35f3b1b89b5a5de516840692c131675
# Parent  728aaeea12fdcc5d7849ba61c5cc27978df86fa7
Make OpenSSL usage thread-safe (closes #206)

Enable OpenSSL’s multithreading support by defining locking and
thread-ID callbacks.  Remove a lock obviated by this change.

diff -r 728aaeea12fd -r 52bc5143c35f src/c/openssl.c
--- a/src/c/openssl.c	Wed Jul 29 10:08:03 2015 -0400
+++ b/src/c/openssl.c	Thu Aug 06 10:15:53 2015 -0400
@@ -1,5 +1,6 @@
 #include "config.h"
 
+#include <assert.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -7,12 +8,17 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
+#include <pthread.h>
 
+#include <openssl/crypto.h>
 #include <openssl/sha.h>
 #include <openssl/rand.h>
 
 #define PASSSIZE 4
 
+// OpenSSL locks array.  See threads(3SSL).
+static pthread_mutex_t *openssl_locks;
+
 int uw_hash_blocksize = 32;
 
 static int password[PASSSIZE];
@@ -27,7 +33,41 @@
   }
 }
 
+// OpenSSL callbacks
+static void thread_id(CRYPTO_THREADID *const result) {
+  CRYPTO_THREADID_set_numeric(result, pthread_self());
+}
+static void lock_or_unlock(const int mode, const int type, const char *file,
+                           const int line) {
+  pthread_mutex_t *const lock = &openssl_locks[type];
+  if (mode & CRYPTO_LOCK) {
+    if (pthread_mutex_lock(lock)) {
+      fprintf(stderr, "Can't take lock at %s:%d\n", file, line);
+      exit(1);
+    }
+  } else {
+    if (pthread_mutex_unlock(lock)) {
+      fprintf(stderr, "Can't release lock at %s:%d\n", file, line);
+      exit(1);
+    }
+  }
+}
+
 void uw_init_crypto() {
+  int i;
+  // Set up OpenSSL.
+  assert(openssl_locks == NULL);
+  openssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+  if (!openssl_locks) {
+    perror("malloc");
+    exit(1);
+  }
+  for (i = 0; i < CRYPTO_num_locks(); ++i) {
+    pthread_mutex_init(&(openssl_locks[i]), NULL);
+  }
+  CRYPTO_THREADID_set_callback(thread_id);
+  CRYPTO_set_locking_callback(lock_or_unlock);
+  // Prepare signatures.
   if (uw_sig_file) {
     int fd;
 
diff -r 728aaeea12fd -r 52bc5143c35f src/c/urweb.c
--- a/src/c/urweb.c	Wed Jul 29 10:08:03 2015 -0400
+++ b/src/c/urweb.c	Thu Aug 06 10:15:53 2015 -0400
@@ -167,13 +167,8 @@
 void uw_free_client_data(void *);
 void uw_copy_client_data(void *dst, void *src);
 
-static pthread_mutex_t rand_mutex = PTHREAD_MUTEX_INITIALIZER;
-
 static uw_Basis_int my_rand() {
-  pthread_mutex_lock(&rand_mutex);
   int ret, r = RAND_bytes((unsigned char *)&ret, sizeof ret);
-  pthread_mutex_unlock(&rand_mutex);
-
   if (r)
     return abs(ret);
   else

_______________________________________________
Ur mailing list
[email protected]
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur

Reply via email to