replace use of static master mutex in crypto providers

This commit is contained in:
Stephen Lombardo 2019-11-05 17:10:36 -05:00
parent 924e0ef0f8
commit 4663c5ad5c
2 changed files with 60 additions and 25 deletions

View File

@ -39,38 +39,55 @@
static NSSInitContext* nss_init_context = NULL; static NSSInitContext* nss_init_context = NULL;
static unsigned int nss_init_count = 0; 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); int sqlcipher_nss_setup(sqlcipher_provider *p);
static int sqlcipher_nss_activate(void *ctx) { static int sqlcipher_nss_activate(void *ctx) {
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering static master mutex\n"); if(nss_mutex == NULL){
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: allocating nss_mutex");
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered static master mutex\n"); 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) { if (nss_init_context == NULL) {
nss_init_context = NSS_InitContext("", "", "", "", NULL, nss_init_context = NSS_InitContext("", "", "", "", NULL,
NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT); NSS_INIT_FORCEOPEN | NSS_INIT_OPTIMIZESPACE | NSS_INIT_NOROOTINIT);
} }
nss_init_count++; nss_init_count++;
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving nss_mutex %p\n", nss_mutex);
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); sqlite3_mutex_leave(nss_mutex);
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex);
return SQLITE_OK; return SQLITE_OK;
} }
static int sqlcipher_nss_deactivate(void *ctx) { static int sqlcipher_nss_deactivate(void *ctx) {
CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: entering static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering nss_mutex %p\n", nss_mutex);
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); sqlite3_mutex_enter(nss_mutex);
CODEC_TRACE_MUTEX("sqlcipher_nss_deactivate: entered static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex);
nss_init_count--; nss_init_count--;
if (nss_init_count == 0 && nss_init_context != NULL) { if (nss_init_count == 0 && nss_init_context != NULL) {
sqlite3_mutex *temp_mutex;
NSS_ShutdownContext(nss_init_context); NSS_ShutdownContext(nss_init_context);
nss_init_context = NULL; 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; return SQLITE_OK;
} }

View File

@ -47,6 +47,7 @@ typedef struct {
static unsigned int openssl_external_init = 0; static unsigned int openssl_external_init = 0;
static unsigned int openssl_init_count = 0; static unsigned int openssl_init_count = 0;
static sqlite3_mutex* openssl_rand_mutex = NULL; 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) #if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
static HMAC_CTX *HMAC_CTX_new(void) 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 /* initialize openssl and increment the internal init counter
but only if it hasn't been initalized outside of SQLCipher by this program but only if it hasn't been initalized outside of SQLCipher by this program
e.g. on startup */ e.g. on startup */
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering static master mutex");
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); if(openssl_activate_mutex == NULL){
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered static master mutex"); 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_init_count == 0 && EVP_get_cipherbyname(OPENSSL_CIPHER) != NULL) {
/* if openssl has not yet been initialized by this library, but /* if openssl has not yet been initialized by this library, but
@ -136,9 +144,9 @@ static int sqlcipher_openssl_activate(void *ctx) {
#endif #endif
openssl_init_count++; openssl_init_count++;
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving static master mutex"); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex);
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); sqlite3_mutex_leave(openssl_activate_mutex);
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left static master mutex"); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex);
return SQLITE_OK; 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 freeing the EVP structures on the final deactivation to ensure that
OpenSSL memory is cleaned up */ OpenSSL memory is cleaned up */
static int sqlcipher_openssl_deactivate(void *ctx) { static int sqlcipher_openssl_deactivate(void *ctx) {
CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering static master mutex"); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex);
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); sqlite3_mutex_enter(openssl_activate_mutex);
CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered static master mutex"); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex);
openssl_init_count--; openssl_init_count--;
if(openssl_init_count == 0) { if(openssl_init_count == 0) {
sqlite3_mutex *temp_mutex;
if(openssl_external_init == 0) { if(openssl_external_init == 0) {
/* if OpenSSL hasn't be initialized externally, and the counter reaches zero /* if OpenSSL hasn't be initialized externally, and the counter reaches zero
after it's decremented, release EVP memory 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); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_rand_mutex %p", openssl_rand_mutex);
openssl_rand_mutex = NULL; openssl_rand_mutex = NULL;
#endif #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; return SQLITE_OK;
} }