8000 mutex around RAND_bytes() · magic-coder/sqlcipher@f3389d2 · GitHub
[go: up one dir, main page]

Skip to content

Commit f3389d2

Browse files
committed
mutex around RAND_bytes()
1 parent 573d7b2 commit f3389d2

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

src/crypto_openssl.c

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ typedef struct {
4545

4646
static unsigned int openssl_external_init = 0;
4747
static unsigned int openssl_init_count = 0;
48-
48+
static sqlite3_mutex* openssl_rand_mutex = NULL;
4949

5050
static int sqlciphe 8000 r_openssl_add_random(void *ctx, void *buffer, int length) {
51+
sqlite3_mutex_enter(openssl_rand_mutex);
5152
RAND_add(buffer, length, 0);
53+
sqlite3_mutex_leave(openssl_rand_mutex);
5254
return SQLITE_OK;
5355
}
5456

@@ -59,40 +61,53 @@ static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) {
5961
sqlcipher_openssl_deactivate() will free the EVP structures.
6062
*/
6163
static int sqlcipher_openssl_activate(void *ctx) {
62-
/* we'll initialize openssl and increment the internal init counter
64+
/* initialize openssl and increment the internal init counter
6365
but only if it hasn't been initalized outside of SQLCipher by this program
6466
e.g. on startup */
67+
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
68+
6569
if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
70+
/* if openssl has not yet been initialized by this library, but
71+
a call to get_cipherbyname works, then the openssl library
72+
has been initialized externally already. */
6673
openssl_external_init = 1;
6774
}
6875

69-
if(openssl_external_init == 0) {
70-
if(openssl_init_count == 0) {
71-
OpenSSL_add_all_algorithms();
72-
}
73-
openssl_init_count++;
76+
if(openssl_init_count == 0 && openssl_external_init == 0) {
77+
/* if the library was not externally initialized, then should be now */
78+
OpenSSL_add_all_algorithms();
7479
}
80+
81+
if(openssl_rand_mutex == NULL) {
82+
/* allocate a mutex to guard against concurrent calls to RAND_bytes() */
83+
openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
84+
}
85+
86+
openssl_init_count++;
87+
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
7588
return SQLITE_OK;
7689
}
7790

7891
/* deactivate SQLCipher, most imporantly decremeting the activation count and
7992
freeing the EVP structures on the final deactivation to ensure that
8093
OpenSSL memory is cleaned up */
8194
static int sqlcipher_openssl_deactivate(void *ctx) {
82-
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
83-
/* If it is initialized externally, then the init counter should never be greater than zero.
84-
This should prevent SQLCipher from "cleaning up" openssl
85-
when something else in the program might be using it. */
86-
if(openssl_external_init == 0) {
87-
openssl_init_count--;
88-
/* if the counter reaches zero after it's decremented release EVP memory
95+
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
96+
openssl_init_count--;
97+
98+
if(openssl_init_count == 0) {
99+
if(openssl_external_init == 0) {
100+
/* if OpenSSL hasn't be initialized externally, and the counter reaches zero
101+
after it's decremented, release EVP memory
89102
Note: this code will only be reached if OpensSSL_add_all_algorithms()
90-
is called by SQLCipher internally. */
91-
if(openssl_init_count == 0) {
103+
is called by SQLCipher internally. This should prevent SQLCipher from
104+
"cleaning up" openssl when it was initialized externally by the program */
92105
EVP_cleanup();
93106
}
107+
sqlite3_mutex_free(openssl_rand_mutex);
108+
openssl_rand_mutex = NULL;
94109
}
95-
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
110+
sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
96111
return SQLITE_OK;
97112
}
98113

@@ -102,7 +117,17 @@ static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
102117

103118
/* generate a defined number of random bytes */
104119
static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
105-
return (RAND_bytes((unsigned char *)buffer, length) == 1) ? SQLITE_OK : SQLITE_ERROR;
120+
int rc = 0;
121+
/* concurrent calls to RAND_bytes can cause a crash under some openssl versions when a
122+
naive application doesn't use CRYPTO_set_locking_callback and
123+
CRYPTO_THREADID_set_callback to ensure openssl thread safety.
124+
This is simple workaround to prevent this common crash
125+
but a more proper solution is that applications setup platform-appropriate
126+
thread saftey in openssl externally */
127+
sqlite3_mutex_enter(openssl_rand_mutex);
128+
rc = RAND_bytes((unsigned char *)buffer, length);
129+
sqlite3_mutex_leave(openssl_rand_mutex);
130+
return (rc == 1) ? SQLITE_OK : SQLITE_ERROR;
106131
}
107132

108133
static int sqlcipher_openssl_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {

0 commit comments

Comments
 (0)
0