From 4663c5ad5c959d2dce20b69b08b3ff2f1f00c6c2 Mon Sep 17 00:00:00 2001 From: Stephen Lombardo Date: Tue, 5 Nov 2019 17:10:36 -0500 Subject: [PATCH] replace use of static master mutex in crypto providers --- src/crypto_nss.c | 43 ++++++++++++++++++++++++++++++------------- src/crypto_openssl.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/crypto_nss.c b/src/crypto_nss.c index 5df1a67..5d81fca 100644 --- a/src/crypto_nss.c +++ b/src/crypto_nss.c @@ -39,38 +39,55 @@ static NSSInitContext* nss_init_context = NULL; static unsigned int nss_init_count = 0; -static sqlite3_mutex* nss_rand_mutex = NULL; +static sqlite3_mutex* nss_mutex = NULL; int sqlcipher_nss_setup(sqlcipher_provider *p); static int sqlcipher_nss_activate(void *ctx) { - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering static master mutex\n"); - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered static master mutex\n"); + if(nss_mutex == NULL){ + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocating nss_mutex"); + nss_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocated nss_mutex %p", nss_mutex); + } + + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex); + sqlite3_mutex_enter(nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); if (nss_init_context == NULL) { nss_init_context = NSS_InitContext("", "", "", "", NULL, NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT); } nss_init_count++; - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving static master mutex\n"); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left static master mutex\n"); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); + sqlite3_mutex_leave(nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); return SQLITE_OK; } static int sqlcipher_nss_deactivate(void *ctx) { - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: entering static master mutex\n"); - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: entered static master mutex\n"); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex); + sqlite3_mutex_enter(nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); + nss_init_count--; if (nss_init_count == 0 && nss_init_context != NULL) { + sqlite3_mutex *temp_mutex; NSS_ShutdownContext(nss_init_context); nss_init_context = NULL; + temp_mutex = nss_mutex; + nss_mutex = NULL; + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); + sqlite3_mutex_leave(temp_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freeing nss_mutex %p", nss_mutex); + sqlite3_mutex_free(temp_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: freed nss_mutex %p", nss_mutex); + } else { + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex); + sqlite3_mutex_leave(nss_mutex); + CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); } - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: leaving static master mutex\n"); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: left static master mutex\n"); return SQLITE_OK; } diff --git a/src/crypto_openssl.c b/src/crypto_openssl.c index 4f7ff3c..ff62228 100644 --- a/src/crypto_openssl.c +++ b/src/crypto_openssl.c @@ -47,6 +47,7 @@ typedef struct { static unsigned int openssl_external_init = 0; static unsigned int openssl_init_count = 0; static sqlite3_mutex* openssl_rand_mutex = NULL; +static sqlite3_mutex* openssl_activate_mutex = NULL; #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) static HMAC_CTX *HMAC_CTX_new(void) @@ -99,9 +100,16 @@ static int sqlcipher_openssl_activate(void *ctx) { /* initialize openssl and increment the internal init counter but only if it hasn't been initalized outside of SQLCipher by this program e.g. on startup */ - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering static master mutex"); - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered static master mutex"); + + if(openssl_activate_mutex == NULL){ + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_activate_mutex"); + openssl_activate_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocated openssl_activate_mutex %p", openssl_activate_mutex); + } + + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex); + sqlite3_mutex_enter(openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex); if(openssl_init_count == 0 && EVP_get_cipherbyname(OPENSSL_CIPHER) != NULL) { /* if openssl has not yet been initialized by this library, but @@ -136,9 +144,9 @@ static int sqlcipher_openssl_activate(void *ctx) { #endif openssl_init_count++; - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving static master mutex"); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left static master mutex"); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); + sqlite3_mutex_leave(openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); return SQLITE_OK; } @@ -146,12 +154,13 @@ static int sqlcipher_openssl_activate(void *ctx) { freeing the EVP structures on the final deactivation to ensure that OpenSSL memory is cleaned up */ static int sqlcipher_openssl_deactivate(void *ctx) { - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering static master mutex"); - sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered static master mutex"); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex); + sqlite3_mutex_enter(openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex); openssl_init_count--; if(openssl_init_count == 0) { + sqlite3_mutex *temp_mutex; if(openssl_external_init == 0) { /* if OpenSSL hasn't be initialized externally, and the counter reaches zero after it's decremented, release EVP memory @@ -170,10 +179,19 @@ static int sqlcipher_openssl_deactivate(void *ctx) { CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_rand_mutex %p", openssl_rand_mutex); openssl_rand_mutex = NULL; #endif + temp_mutex = openssl_activate_mutex; + openssl_activate_mutex = NULL; + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); + sqlite3_mutex_leave(temp_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freeing openssl_activate_mutex %p", openssl_activate_mutex); + sqlite3_mutex_free(temp_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_activate_mutex %p", openssl_activate_mutex); + } else { + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); + sqlite3_mutex_leave(openssl_activate_mutex); + CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); } - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: leaving static master mutex"); - sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); - CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: left static master mutex"); return SQLITE_OK; }