From e15f563368343bb92a014c6a9ccb2fc5dfab8843 Mon Sep 17 00:00:00 2001 From: Yossi Gottlieb Date: Sun, 10 May 2020 17:35:27 +0300 Subject: [PATCH] TLS: Add crypto locks for older OpenSSL support. This is really required only for older OpenSSL versions. Also, at the moment Redis does not use OpenSSL from multiple threads so this will only be useful if modules end up doing that. --- src/tls.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/tls.c b/src/tls.c index c18aafebe..cfd6ea234 100644 --- a/src/tls.c +++ b/src/tls.c @@ -93,11 +93,56 @@ static int parseProtocolsConfig(const char *str) { * served to the reader yet. */ static list *pending_list = NULL; +/** + * OpenSSL global initialization and locking handling callbacks. + * Note that this is only required for OpenSSL < 1.1.0. + */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define USE_CRYPTO_LOCKS +#endif + +#ifdef USE_CRYPTO_LOCKS + +static pthread_mutex_t *openssl_locks; + +static void sslLockingCallback(int mode, int lock_id, const char *f, int line) { + pthread_mutex_t *mt = openssl_locks + lock_id; + + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(mt); + } else { + pthread_mutex_unlock(mt); + } + + (void)f; + (void)line; +} + +static void initCryptoLocks(void) { + unsigned i, nlocks; + if (CRYPTO_get_locking_callback() != NULL) { + /* Someone already set the callback before us. Don't destroy it! */ + return; + } + nlocks = CRYPTO_num_locks(); + openssl_locks = zmalloc(sizeof(*openssl_locks) * nlocks); + for (i = 0; i < nlocks; i++) { + pthread_mutex_init(openssl_locks + i, NULL); + } + CRYPTO_set_locking_callback(sslLockingCallback); +} +#endif /* USE_CRYPTO_LOCKS */ + void tlsInit(void) { ERR_load_crypto_strings(); SSL_load_error_strings(); SSL_library_init(); +#ifdef USE_CRYPTO_LOCKS + initCryptoLocks(); +#endif + if (!RAND_poll()) { serverLog(LL_WARNING, "OpenSSL: Failed to seed random number generator."); }