major rework of mutex allocation and management

This commit is contained in:
Stephen Lombardo 2019-11-06 13:56:00 -05:00
parent 4663c5ad5c
commit 872fb0078f
5 changed files with 142 additions and 163 deletions

View File

@ -56,9 +56,15 @@ static volatile int mem_security_initialized = 0;
static volatile int mem_security_activated = 0; static volatile int mem_security_activated = 0;
static volatile unsigned int sqlcipher_activate_count = 0; static volatile unsigned int sqlcipher_activate_count = 0;
static volatile sqlite3_mem_methods default_mem_methods; static volatile sqlite3_mem_methods default_mem_methods;
static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
static sqlcipher_provider *default_provider = NULL; static sqlcipher_provider *default_provider = NULL;
static sqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT];
sqlite3_mutex* sqlcipher_mutex(int mutex) {
if(mutex < 0 || mutex >= SQLCIPHER_MUTEX_COUNT) return NULL;
return sqlcipher_static_mutex[mutex];
}
static int sqlcipher_mem_init(void *pAppData) { static int sqlcipher_mem_init(void *pAppData) {
return default_mem_methods.xInit(pAppData); return default_mem_methods.xInit(pAppData);
} }
@ -116,9 +122,9 @@ void sqlcipher_init_memmethods() {
} }
int sqlcipher_register_provider(sqlcipher_provider *p) { int sqlcipher_register_provider(sqlcipher_provider *p) {
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering SQLCIPHER_MUTEX_PROVIDER\n");
sqlite3_mutex_enter(sqlcipher_provider_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered SQLCIPHER_MUTEX_PROVIDER"\n);
if(default_provider != NULL && default_provider != p) { if(default_provider != NULL && default_provider != p) {
/* only free the current registerd provider if it has been initialized /* only free the current registerd provider if it has been initialized
@ -127,9 +133,9 @@ int sqlcipher_register_provider(sqlcipher_provider *p) {
sqlcipher_free(default_provider, sizeof(sqlcipher_provider)); sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
} }
default_provider = p; default_provider = p;
CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving SQLCIPHER_MUTEX_PROVIDER\n");
sqlite3_mutex_leave(sqlcipher_provider_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_register_provider: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_register_provider: left SQLCIPHER_MUTEX_PROVIDER\n");
return SQLITE_OK; return SQLITE_OK;
} }
@ -146,11 +152,12 @@ void sqlcipher_activate() {
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n");
if(sqlcipher_provider_mutex == NULL) { /* allocate new mutexes */
/* allocate a new mutex to guard access to the provider */ if(sqlcipher_activate_count == 0) {
CODEC_TRACE_MUTEX("sqlcipher_activate: allocating sqlcipher provider mutex\n"); int i;
sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) {
CODEC_TRACE_MUTEX("sqlcipher_activate: allocated sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); sqlcipher_static_mutex[i] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
}
} }
/* check to see if there is a provider registered at this point /* check to see if there is a provider registered at this point
@ -196,30 +203,32 @@ void sqlcipher_deactivate() {
sqlcipher_activate_count--; sqlcipher_activate_count--;
/* if no connections are using sqlcipher, cleanup globals */ /* if no connections are using sqlcipher, cleanup globals */
if(sqlcipher_activate_count < 1) { if(sqlcipher_activate_count < 1) {
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
sqlite3_mutex_enter(sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering SQLCIPHER_MUTEX_PROVIDER\n");
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered SQLCIPHER_MUTEX_PROVIDER\n");
if(default_provider != NULL) { if(default_provider != NULL) {
sqlcipher_free(default_provider, sizeof(sqlcipher_provider)); sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
default_provider = NULL; default_provider = NULL;
} }
CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER\n");
sqlite3_mutex_leave(sqlcipher_provider_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_deactivate: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_deactivate: left SQLCIPHER_MUTEX_PROVIDER\n");
/* last connection closed, free provider mutex*/
CODEC_TRACE_MUTEX("sqlcipher_deactivate: freeing sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
sqlite3_mutex_free(sqlcipher_provider_mutex);
CODEC_TRACE_MUTEX("sqlcipher_deactivate: freed sqlcipher provider mutex %p\n", sqlcipher_provider_mutex);
sqlcipher_provider_mutex = NULL;
sqlcipher_activate_count = 0; /* reset activation count */
#ifdef SQLCIPHER_EXT #ifdef SQLCIPHER_EXT
sqlcipher_ext_provider_destroy(); sqlcipher_ext_provider_destroy();
#endif #endif
/* last connection closed, free mutexes */
if(sqlcipher_activate_count == 0) {
int i;
for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) {
sqlite3_mutex_free(sqlcipher_static_mutex[i]);
}
}
sqlcipher_activate_count = 0; /* reset activation count */
} }
CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n"); CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n");
@ -845,15 +854,15 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, const voi
if(ctx->provider == NULL) return SQLITE_NOMEM; if(ctx->provider == NULL) return SQLITE_NOMEM;
/* make a copy of the provider to be used for the duration of the context */ /* make a copy of the provider to be used for the duration of the context */
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering SQLCIPHER_MUTEX_PROVIDER\n");
sqlite3_mutex_enter(sqlcipher_provider_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered SQLCIPHER_MUTEX_PROVIDER\n");
memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider)); memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving SQLCIPHER_MUTEX_PROVIDER\n");
sqlite3_mutex_leave(sqlcipher_provider_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER));
CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left sqlcipher provider mutex %p\n", sqlcipher_provider_mutex); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left SQLCIPHER_MUTEX_PROVIDER\n");
CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n"); CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n");
if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc; if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;

View File

@ -39,7 +39,6 @@
static prng_state prng; static prng_state prng;
static volatile unsigned int ltc_init = 0; static volatile unsigned int ltc_init = 0;
static volatile unsigned int ltc_ref_count = 0; static volatile unsigned int ltc_ref_count = 0;
static sqlite3_mutex* ltc_rand_mutex = NULL;
#define LTC_CIPHER "rijndael" #define LTC_CIPHER "rijndael"
@ -48,34 +47,37 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
int data_to_read = length; int data_to_read = length;
int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ; int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
const unsigned char * data = (const unsigned char *)buffer; const unsigned char * data = (const unsigned char *)buffer;
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
sqlite3_mutex_enter(ltc_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
while(data_to_read > 0){ CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
rc = fortuna_add_entropy(data, block_sz, &prng);
rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK; while(data_to_read > 0){
if(rc != SQLITE_OK){ rc = fortuna_add_entropy(data, block_sz, &prng);
break; rc = rc != CRYPT_OK ? SQLITE_ERROR : SQLITE_OK;
} if(rc != SQLITE_OK){
data_to_read -= block_sz; break;
data += block_sz;
block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
} }
fortuna_ready(&prng); data_to_read -= block_sz;
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND data += block_sz;
sqlite3_mutex_leave(ltc_rand_mutex); block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
#endif }
fortuna_ready(&prng);
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_ltc_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
return rc; return rc;
} }
static int sqlcipher_ltc_activate(void *ctx) { static int sqlcipher_ltc_activate(void *ctx) {
unsigned char random_buffer[FORTUNA_MAX_SZ]; unsigned char random_buffer[FORTUNA_MAX_SZ];
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
if(ltc_rand_mutex == NULL){ CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
} CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_enter(ltc_rand_mutex);
#endif
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
if(ltc_init == 0) { if(ltc_init == 0) {
if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR; if(register_prng(&fortuna_desc) < 0) return SQLITE_ERROR;
@ -86,41 +88,42 @@ static int sqlcipher_ltc_activate(void *ctx) {
if(fortuna_start(&prng) != CRYPT_OK) { if(fortuna_start(&prng) != CRYPT_OK) {
return SQLITE_ERROR; return SQLITE_ERROR;
} }
ltc_init = 1; ltc_init = 1;
} }
ltc_ref_count++; ltc_ref_count++;
#ifndef SQLCIPHER_TEST #ifndef SQLCIPHER_TEST
sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer); sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
#endif #endif
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
sqlite3_mutex_leave(ltc_rand_mutex);
#endif
if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) { if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
return SQLITE_ERROR; return SQLITE_ERROR;
} }
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ); sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_ltc_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
return SQLITE_OK; return SQLITE_OK;
} }
static int sqlcipher_ltc_deactivate(void *ctx) { static int sqlcipher_ltc_deactivate(void *ctx) {
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_enter(ltc_rand_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
#endif CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
ltc_ref_count--; ltc_ref_count--;
if(ltc_ref_count == 0){ if(ltc_ref_count == 0){
fortuna_done(&prng); fortuna_done(&prng);
sqlcipher_memset((void *)&prng, 0, sizeof(prng)); sqlcipher_memset((void *)&prng, 0, sizeof(prng));
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
sqlite3_mutex_leave(ltc_rand_mutex);
sqlite3_mutex_free(ltc_rand_mutex);
ltc_rand_mutex = NULL;
#endif
} }
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
else { CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_leave(ltc_rand_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
} CODEC_TRACE_MUTEX("sqlcipher_ltc_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
#endif
return SQLITE_OK; return SQLITE_OK;
} }
@ -133,13 +136,16 @@ static const char* sqlcipher_ltc_get_provider_version(void *ctx) {
} }
static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) { static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_enter(ltc_rand_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
#endif CODEC_TRACE_MUTEX("sqlcipher_ltc_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
fortuna_read(buffer, length, &prng); fortuna_read(buffer, length, &prng);
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
sqlite3_mutex_leave(ltc_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_ltc_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_ltc_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
return SQLITE_OK; return SQLITE_OK;
} }

View File

@ -39,55 +39,40 @@
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_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) {
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); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_enter(nss_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
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 nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_leave(nss_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
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_activate: entering nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_enter(nss_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
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); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_leave(temp_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left nss_mutex %p\n", nss_mutex); CODEC_TRACE_MUTEX("sqlcipher_nss_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
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);
}
return SQLITE_OK; return SQLITE_OK;
} }

View File

@ -46,8 +46,6 @@ 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_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)
@ -74,15 +72,15 @@ static void HMAC_CTX_free(HMAC_CTX *ctx)
static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) { static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering openssl_rand_mutex %p\n", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_enter(openssl_rand_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered openssl_rand_mutex %p\n", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif #endif
RAND_add(buffer, length, 0); RAND_add(buffer, length, 0);
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving openssl_rand_mutex %p\n", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_leave(openssl_rand_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left openssl_rand_mutex %p\n", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif #endif
return SQLITE_OK; return SQLITE_OK;
} }
@ -101,15 +99,9 @@ static int sqlcipher_openssl_activate(void *ctx) {
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 */
if(openssl_activate_mutex == NULL){ CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_activate_mutex"); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
openssl_activate_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
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
@ -134,19 +126,10 @@ static int sqlcipher_openssl_activate(void *ctx) {
#endif #endif
} }
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
if(openssl_rand_mutex == NULL) {
/* allocate a mutex to guard against concurrent calls to RAND_bytes() */
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocating openssl_rand_mutex");
openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: allocated openssl_rand_mutex %p", openssl_rand_mutex);
}
#endif
openssl_init_count++; openssl_init_count++;
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving openssl_activate_mutex %p\n", openssl_activate_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_leave(openssl_activate_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left openssl_activate_mutex %p\n", openssl_activate_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
return SQLITE_OK; return SQLITE_OK;
} }
@ -154,9 +137,9 @@ 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_activate: entering openssl_activate_mutex %p\n", openssl_activate_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
sqlite3_mutex_enter(openssl_activate_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered openssl_activate_mutex %p\n", openssl_activate_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
openssl_init_count--; openssl_init_count--;
if(openssl_init_count == 0) { if(openssl_init_count == 0) {
@ -173,25 +156,11 @@ static int sqlcipher_openssl_deactivate(void *ctx) {
} else { } else {
openssl_external_init = 0; openssl_external_init = 0;
} }
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND }
CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freeing openssl_rand_mutex %p", openssl_rand_mutex);
sqlite3_mutex_free(openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: freed openssl_rand_mutex %p", openssl_rand_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE));
openssl_rand_mutex = NULL; CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n");
#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);
}
return SQLITE_OK; return SQLITE_OK;
} }
@ -213,15 +182,15 @@ static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
but a more proper solution is that applications setup platform-appropriate but a more proper solution is that applications setup platform-appropriate
thread saftey in openssl externally */ thread saftey in openssl externally */
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering openssl_rand_mutex %p", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_enter(openssl_rand_mutex); sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered openssl_rand_mutex %p", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif #endif
rc = RAND_bytes((unsigned char *)buffer, length); rc = RAND_bytes((unsigned char *)buffer, length);
#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving openssl_rand_mutex %p", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n");
sqlite3_mutex_leave(openssl_rand_mutex); sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND));
CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left openssl_rand_mutex %p", openssl_rand_mutex); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n");
#endif #endif
return (rc == 1) ? SQLITE_OK : SQLITE_ERROR; return (rc == 1) ? SQLITE_OK : SQLITE_ERROR;
} }

View File

@ -87,6 +87,16 @@ void sqlcipher_free(void *, int);
int sqlcipher_register_provider(sqlcipher_provider *); int sqlcipher_register_provider(sqlcipher_provider *);
sqlcipher_provider* sqlcipher_get_provider(void); sqlcipher_provider* sqlcipher_get_provider(void);
#define SQLCIPHER_MUTEX_PROVIDER 0
#define SQLCIPHER_MUTEX_PROVIDER_ACTIVATE 1
#define SQLCIPHER_MUTEX_PROVIDER_RAND 2
#define SQLCIPHER_MUTEX_RESERVED1 3
#define SQLCIPHER_MUTEX_RESERVED2 4
#define SQLCIPHER_MUTEX_RESERVED3 5
#define SQLCIPHER_MUTEX_COUNT 6
sqlite3_mutex* sqlcipher_mutex(int);
#endif #endif
#endif #endif
/* END SQLCIPHER */ /* END SQLCIPHER */