From 4d1178cc2447c2b993ed565f62afdf7eb8fe367b Mon Sep 17 00:00:00 2001 From: Yossi Gottlieb Date: Sun, 10 May 2020 17:38:04 +0300 Subject: [PATCH 1/4] TLS: Fix test failures on recent Debian/Ubuntu. Seems like on some systems choosing specific TLS v1/v1.1 versions no longer works as expected. Test is reduced for v1.2 now which is still good enough to test the mechansim, and matters most anyway. --- tests/unit/tls.tcl | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/unit/tls.tcl b/tests/unit/tls.tcl index 950f65557..2b04590cd 100644 --- a/tests/unit/tls.tcl +++ b/tests/unit/tls.tcl @@ -25,26 +25,6 @@ start_server {tags {"tls"}} { } test {TLS: Verify tls-protocols behaves as expected} { - r CONFIG SET tls-protocols TLSv1 - - set s [redis [srv 0 host] [srv 0 port] 0 1 {-tls1 0}] - catch {$s PING} e - assert_match {*I/O error*} $e - - set s [redis [srv 0 host] [srv 0 port] 0 1 {-tls1 1}] - catch {$s PING} e - assert_match {PONG} $e - - r CONFIG SET tls-protocols TLSv1.1 - - set s [redis [srv 0 host] [srv 0 port] 0 1 {-tls1.1 0}] - catch {$s PING} e - assert_match {*I/O error*} $e - - set s [redis [srv 0 host] [srv 0 port] 0 1 {-tls1.1 1}] - catch {$s PING} e - assert_match {PONG} $e - r CONFIG SET tls-protocols TLSv1.2 set s [redis [srv 0 host] [srv 0 port] 0 1 {-tls1.2 0}] From 450f0d724834cf5d4d32d6d8caae7e4167c184b8 Mon Sep 17 00:00:00 2001 From: Yossi Gottlieb Date: Sun, 10 May 2020 17:35:27 +0300 Subject: [PATCH 2/4] 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."); } From 4715ce59037d5806ede71e605f53b1addb7014ed Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 12 May 2020 21:19:12 +0100 Subject: [PATCH 3/4] NetBSD build update. This platform supports CPU affinity (but not OpenBSD). --- src/Makefile | 10 ++++++++++ src/config.h | 2 +- src/setcpuaffinity.c | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 55f862cfc..b8c05c32b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -128,6 +128,14 @@ else ifeq ($(uname_S),DragonFly) # FreeBSD FINAL_LIBS+= -lpthread -lexecinfo +else +ifeq ($(uname_S),OpenBSD) + # OpenBSD + FINAL_LIBS+= -lpthread -lexecinfo +else +ifeq ($(uname_S),NetBSD) + # NetBSD + FINAL_LIBS+= -lpthread -lexecinfo else # All the other OSes (notably Linux) FINAL_LDFLAGS+= -rdynamic @@ -138,6 +146,8 @@ endif endif endif endif +endif +endif # Include paths to dependencies FINAL_CFLAGS+= -I../deps/hiredis -I../deps/linenoise -I../deps/lua/src diff --git a/src/config.h b/src/config.h index 6025d4e96..0fcc42972 100644 --- a/src/config.h +++ b/src/config.h @@ -248,7 +248,7 @@ int pthread_setname_np(const char *name); #endif /* Check if we can use setcpuaffinity(). */ -#if (defined __linux || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__) +#if (defined __linux || defined __NetBSD__ || defined __FreeBSD__) #define USE_SETCPUAFFINITY void setcpuaffinity(const char *cpulist); #endif diff --git a/src/setcpuaffinity.c b/src/setcpuaffinity.c index dcae81c71..13594113c 100644 --- a/src/setcpuaffinity.c +++ b/src/setcpuaffinity.c @@ -36,6 +36,10 @@ #include #include #endif +#ifdef __NetBSD__ +#include +#include +#endif #include "config.h" #ifdef USE_SETCPUAFFINITY @@ -71,11 +75,18 @@ void setcpuaffinity(const char *cpulist) { #ifdef __FreeBSD__ cpuset_t cpuset; #endif +#ifdef __NetBSD__ + cpuset_t *cpuset; +#endif if (!cpulist) return; +#ifndef __NetBSD__ CPU_ZERO(&cpuset); +#else + cpuset = cpuset_create(); +#endif q = cpulist; while (p = q, q = next_token(q, ','), p) { @@ -110,7 +121,11 @@ void setcpuaffinity(const char *cpulist) { return; while (a <= b) { +#ifndef __NetBSD__ CPU_SET(a, &cpuset); +#else + cpuset_set(a, cpuset); +#endif a += s; } } @@ -124,6 +139,10 @@ void setcpuaffinity(const char *cpulist) { #ifdef __FreeBSD__ cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset), &cpuset); #endif +#ifdef __NetBSD__ + pthread_setaffinity_np(pthread_self(), cpuset_size(cpuset), cpuset); + cpuset_destroy(cpuset); +#endif } #endif /* USE_SETCPUAFFINITY */ From 41cabca2ab4478c3288d0d97419f4412785652bc Mon Sep 17 00:00:00 2001 From: Madelyn Olson Date: Thu, 14 May 2020 08:37:24 -0700 Subject: [PATCH 4/4] Added a refcount on timer events to prevent deletion of recursive timer calls --- src/ae.c | 10 ++++++++++ src/ae.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/ae.c b/src/ae.c index 379cfd1e6..689a27d16 100644 --- a/src/ae.c +++ b/src/ae.c @@ -238,6 +238,7 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, te->clientData = clientData; te->prev = NULL; te->next = eventLoop->timeEventHead; + te->refcount = 0; if (te->next) te->next->prev = te; eventLoop->timeEventHead = te; @@ -316,6 +317,13 @@ static int processTimeEvents(aeEventLoop *eventLoop) { /* Remove events scheduled for deletion. */ if (te->id == AE_DELETED_EVENT_ID) { aeTimeEvent *next = te->next; + /* If a reference exists for this timer event, + * don't free it. This is currently incremented + * for recursive timerProc calls */ + if (te->refcount) { + te = next; + continue; + } if (te->prev) te->prev->next = te->next; else @@ -345,7 +353,9 @@ static int processTimeEvents(aeEventLoop *eventLoop) { int retval; id = te->id; + te->refcount++; retval = te->timeProc(eventLoop, id, te->clientData); + te->refcount--; processed++; if (retval != AE_NOMORE) { aeAddMillisecondsToNow(retval,&te->when_sec,&te->when_ms); diff --git a/src/ae.h b/src/ae.h index 63b306615..d1b7f34bf 100644 --- a/src/ae.h +++ b/src/ae.h @@ -86,6 +86,8 @@ typedef struct aeTimeEvent { void *clientData; struct aeTimeEvent *prev; struct aeTimeEvent *next; + int refcount; /* refcount to prevent timer events from being + * freed in recursive time event calls. */ } aeTimeEvent; /* A fired event */