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
