From 8c5aeb6c4c7d0a7a31f43cff5419200e8c55723b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Fri, 24 Aug 2018 11:21:27 +0200 Subject: [PATCH 1/3] Use TLS variables to store RNG state, make RNG lockless --- CHANGES | 3 +++ lib/dns/tests/dnstest.c | 5 +++-- lib/isc/random.c | 14 +++++++++++++- lib/isc/xoshiro128starstar.c | 19 +++++++++++++++++-- lib/ns/tests/nstest.c | 4 ++-- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index feacd18373..03bafd02bf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5020. [func] RNG uses thread-local storage instead of locks, if + supported by platform. [GL #496] + 5019. [cleanup] A message is now logged when ixfr-from-differences is set at zone level for an inline-signed zone. [GL #470] diff --git a/lib/dns/tests/dnstest.c b/lib/dns/tests/dnstest.c index 11f344838a..3761abc7f0 100644 --- a/lib/dns/tests/dnstest.c +++ b/lib/dns/tests/dnstest.c @@ -161,18 +161,19 @@ dns_test_begin(FILE *logfile, bool start_managers) { void dns_test_end(void) { + cleanup_managers(); + if (dst_active) { dst_lib_destroy(); dst_active = false; } - cleanup_managers(); - if (lctx != NULL) isc_log_destroy(&lctx); if (mctx != NULL) isc_mem_destroy(&mctx); + } /* diff --git a/lib/isc/random.c b/lib/isc/random.c index 63b84cd46f..9cf635a37f 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -62,14 +62,26 @@ */ #include "xoshiro128starstar.c" +#if defined(HAVE_TLS) +#if defined(HAVE_THREAD_LOCAL) +static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT; +#elif defined(HAVE___THREAD) +static __thread isc_once_t isc_random_once = ISC_ONCE_INIT; +#else +#error "Unknown method for defining a TLS variable!" +#endif +#else static isc_once_t isc_random_once = ISC_ONCE_INIT; +#endif static void isc_random_initialize(void) { #if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION memset(seed, 0, sizeof(seed)); #else - isc_entropy_get(seed, sizeof(seed)); + int useed[4] = {0,0,0,0}; + isc_entropy_get(useed, sizeof(useed)); + memcpy(seed, useed, sizeof(seed)); #endif } diff --git a/lib/isc/xoshiro128starstar.c b/lib/isc/xoshiro128starstar.c index bff2e3ad38..9df1b4ba74 100644 --- a/lib/isc/xoshiro128starstar.c +++ b/lib/isc/xoshiro128starstar.c @@ -34,6 +34,19 @@ * * The state must be seeded so that it is not everywhere zero. */ +#if defined(HAVE_TLS) +#define _LOCK() {}; +#define _UNLOCK() {}; + +#if defined(HAVE_THREAD_LOCAL) +static thread_local uint32_t seed[4]; +#elif defined(HAVE___THREAD) +static __thread uint32_t seed[4]; +#else +#error "Unknown method for defining a TLS variable!" +#endif + +#else #if defined(_WIN32) || defined(_WIN64) #include static volatile HANDLE _mutex = NULL; @@ -65,12 +78,14 @@ static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; #define _UNLOCK() pthread_mutex_unlock(&_mutex) #endif /* defined(_WIN32) || defined(_WIN64) */ +static uint32_t seed[4]; + +#endif /* defined(HAVE_TLS) */ + static inline uint32_t rotl(const uint32_t x, int k) { return (x << k) | (x >> (32 - k)); } -static uint32_t seed[4]; - static inline uint32_t next(void) { uint32_t result_starstar, t; diff --git a/lib/ns/tests/nstest.c b/lib/ns/tests/nstest.c index ccbe1f65a6..662426f75d 100644 --- a/lib/ns/tests/nstest.c +++ b/lib/ns/tests/nstest.c @@ -277,13 +277,13 @@ ns_test_begin(FILE *logfile, bool start_managers) { void ns_test_end(void) { + cleanup_managers(); + if (dst_active) { dst_lib_destroy(); dst_active = false; } - cleanup_managers(); - if (lctx != NULL) isc_log_destroy(&lctx); From 18ebcf2b30aec2f792678dea3d86a6201c20ebc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Sat, 25 Aug 2018 13:25:51 +0200 Subject: [PATCH 2/3] Add runtime check on top of pthread_mutex_{lock,unlock} in rng --- lib/isc/xoshiro128starstar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/isc/xoshiro128starstar.c b/lib/isc/xoshiro128starstar.c index 9df1b4ba74..bc08e6740f 100644 --- a/lib/isc/xoshiro128starstar.c +++ b/lib/isc/xoshiro128starstar.c @@ -74,8 +74,8 @@ static volatile HANDLE _mutex = NULL; #include static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; -#define _LOCK() pthread_mutex_lock(&_mutex) -#define _UNLOCK() pthread_mutex_unlock(&_mutex) +#define _LOCK() RUNTIME_CHECK(pthread_mutex_lock(&_mutex)==0) +#define _UNLOCK() RUNTIME_CHECK(pthread_mutex_unlock(&_mutex)==0) #endif /* defined(_WIN32) || defined(_WIN64) */ static uint32_t seed[4]; From 7ab228cf7187b2eb76e197f6be4cb686f3e39820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Sat, 25 Aug 2018 13:29:27 +0200 Subject: [PATCH 3/3] Use __declspec( thread ) for thread local storage when compiling with Visual Studio 2015 and higher --- lib/isc/random.c | 2 ++ lib/isc/win32/include/isc/platform.h.in | 5 +++++ lib/isc/xoshiro128starstar.c | 2 ++ 3 files changed, 9 insertions(+) diff --git a/lib/isc/random.c b/lib/isc/random.c index 9cf635a37f..3f49cb512f 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -67,6 +67,8 @@ static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT; #elif defined(HAVE___THREAD) static __thread isc_once_t isc_random_once = ISC_ONCE_INIT; +#elif defined(HAVE___DECLSPEC_THREAD) +static __declspec( thread ) isc_once_t isc_random_once = ISC_ONCE_INIT; #else #error "Unknown method for defining a TLS variable!" #endif diff --git a/lib/isc/win32/include/isc/platform.h.in b/lib/isc/win32/include/isc/platform.h.in index 7f2bdbfb6b..691ac00122 100644 --- a/lib/isc/win32/include/isc/platform.h.in +++ b/lib/isc/win32/include/isc/platform.h.in @@ -16,6 +16,11 @@ ***** Platform-dependent defines. *****/ +#if _MSC_VER > 1400 +#define HAVE_TLS 1 +#define HAVE___DECLSPEC_THREAD 1 +#endif + /* * Some compatibility cludges */ diff --git a/lib/isc/xoshiro128starstar.c b/lib/isc/xoshiro128starstar.c index bc08e6740f..fb71a24419 100644 --- a/lib/isc/xoshiro128starstar.c +++ b/lib/isc/xoshiro128starstar.c @@ -42,6 +42,8 @@ static thread_local uint32_t seed[4]; #elif defined(HAVE___THREAD) static __thread uint32_t seed[4]; +#elif defined(HAVE___DECLSPEC_THREAD) +static __declspec( thread ) uint32_t seed[4]; #else #error "Unknown method for defining a TLS variable!" #endif