forked from wolfSSL/wolfssl
wolfssl/wolfcrypt/wc_port.h: add definition for WOLFSSL_MUTEX_INITIALIZER, currently only #ifdef WOLFSSL_PTHREADS.
src/ssl.c: refactor dynamics of count_mutex, count_mutex_valid, and initRefCount, to be intrinsically race-free on pthreads builds, and to be always race-free for callers that call wolfSSL_Init() first, then wait for return before any other wolfSSL calls, and call wolfSSL_Cleanup() at most as many times as wolfSSL_Init(). also, in AddSessionToClientCache(), move final access to ClientCache inside the lock-protected span, to mollify Coverity.
This commit is contained in:
53
src/ssl.c
53
src/ssl.c
@ -1265,8 +1265,12 @@ int wolfSSL_send_session(WOLFSSL* ssl)
|
|||||||
|
|
||||||
/* prevent multiple mutex initializations */
|
/* prevent multiple mutex initializations */
|
||||||
static volatile WOLFSSL_GLOBAL int initRefCount = 0;
|
static volatile WOLFSSL_GLOBAL int initRefCount = 0;
|
||||||
|
#ifdef WOLFSSL_MUTEX_INITIALIZER
|
||||||
|
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex = WOLFSSL_MUTEX_INITIALIZER;
|
||||||
|
#else
|
||||||
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex; /* init ref count mutex */
|
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex; /* init ref count mutex */
|
||||||
static WOLFSSL_GLOBAL int count_mutex_valid = 0;
|
static WOLFSSL_GLOBAL int count_mutex_valid = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
|
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
|
||||||
WOLFSSL_METHOD pointer passed in is given to ctx to manage.
|
WOLFSSL_METHOD pointer passed in is given to ctx to manage.
|
||||||
@ -6258,6 +6262,7 @@ int wolfSSL_Init(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
if (ret == WOLFSSL_SUCCESS) {
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
if (wc_InitMutex(&count_mutex) != 0) {
|
if (wc_InitMutex(&count_mutex) != 0) {
|
||||||
WOLFSSL_MSG("Bad Init Mutex count");
|
WOLFSSL_MSG("Bad Init Mutex count");
|
||||||
@ -6267,6 +6272,7 @@ int wolfSSL_Init(void)
|
|||||||
count_mutex_valid = 1;
|
count_mutex_valid = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* !WOLFSSL_MUTEX_INITIALIZER */
|
||||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
|
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
|
||||||
/* OpenSSL registers cleanup using atexit */
|
/* OpenSSL registers cleanup using atexit */
|
||||||
if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
|
if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
|
||||||
@ -13378,21 +13384,30 @@ int wolfSSL_Cleanup(void)
|
|||||||
|
|
||||||
WOLFSSL_ENTER("wolfSSL_Cleanup");
|
WOLFSSL_ENTER("wolfSSL_Cleanup");
|
||||||
|
|
||||||
if (initRefCount == 0)
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
return ret; /* possibly no init yet, but not failure either way */
|
|
||||||
|
|
||||||
if ((count_mutex_valid == 1) && (wc_LockMutex(&count_mutex) != 0)) {
|
|
||||||
WOLFSSL_MSG("Bad Lock Mutex count");
|
|
||||||
ret = BAD_MUTEX_E;
|
|
||||||
}
|
|
||||||
|
|
||||||
release = initRefCount-- == 1;
|
|
||||||
if (initRefCount < 0)
|
|
||||||
initRefCount = 0;
|
|
||||||
|
|
||||||
if (count_mutex_valid == 1) {
|
if (count_mutex_valid == 1) {
|
||||||
wc_UnLockMutex(&count_mutex);
|
#endif
|
||||||
|
if (wc_LockMutex(&count_mutex) != 0) {
|
||||||
|
WOLFSSL_MSG("Bad Lock Mutex count");
|
||||||
|
return BAD_MUTEX_E;
|
||||||
|
}
|
||||||
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (initRefCount > 0) {
|
||||||
|
--initRefCount;
|
||||||
|
if (initRefCount == 0)
|
||||||
|
release = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
|
if (count_mutex_valid == 1) {
|
||||||
|
#endif
|
||||||
|
wc_UnLockMutex(&count_mutex);
|
||||||
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!release)
|
if (!release)
|
||||||
return ret;
|
return ret;
|
||||||
@ -13442,11 +13457,13 @@ int wolfSSL_Cleanup(void)
|
|||||||
#endif
|
#endif
|
||||||
#endif /* !NO_SESSION_CACHE */
|
#endif /* !NO_SESSION_CACHE */
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) {
|
if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) {
|
||||||
if (ret == WOLFSSL_SUCCESS)
|
if (ret == WOLFSSL_SUCCESS)
|
||||||
ret = BAD_MUTEX_E;
|
ret = BAD_MUTEX_E;
|
||||||
}
|
}
|
||||||
count_mutex_valid = 0;
|
count_mutex_valid = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
wolfSSL_RAND_Cleanup();
|
wolfSSL_RAND_Cleanup();
|
||||||
@ -14339,6 +14356,8 @@ ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverI
|
|||||||
{
|
{
|
||||||
int error = -1;
|
int error = -1;
|
||||||
word32 clientRow = 0, clientIdx = 0;
|
word32 clientRow = 0, clientIdx = 0;
|
||||||
|
ClientSession* ret = NULL;
|
||||||
|
|
||||||
(void)useTicket;
|
(void)useTicket;
|
||||||
if (side == WOLFSSL_CLIENT_END
|
if (side == WOLFSSL_CLIENT_END
|
||||||
&& row != INVALID_SESSION_ROW
|
&& row != INVALID_SESSION_ROW
|
||||||
@ -14392,6 +14411,8 @@ ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverI
|
|||||||
ClientCache[clientRow].nextIdx %= CLIENT_SESSIONS_PER_ROW;
|
ClientCache[clientRow].nextIdx %= CLIENT_SESSIONS_PER_ROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = &ClientCache[clientRow].Clients[clientIdx];
|
||||||
|
|
||||||
wc_UnLockMutex(&clisession_mutex);
|
wc_UnLockMutex(&clisession_mutex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -14402,10 +14423,8 @@ ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverI
|
|||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("Skipping client cache");
|
WOLFSSL_MSG("Skipping client cache");
|
||||||
}
|
}
|
||||||
if (error == 0)
|
|
||||||
return &ClientCache[clientRow].Clients[clientIdx];
|
return ret;
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
#endif /* !NO_CLIENT_CACHE */
|
#endif /* !NO_CLIENT_CACHE */
|
||||||
|
|
||||||
|
@ -307,6 +307,9 @@
|
|||||||
#if !defined(WOLFSSL_USE_RWLOCK) || defined(SINGLE_THREADED)
|
#if !defined(WOLFSSL_USE_RWLOCK) || defined(SINGLE_THREADED)
|
||||||
typedef wolfSSL_Mutex wolfSSL_RwLock;
|
typedef wolfSSL_Mutex wolfSSL_RwLock;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WOLFSSL_PTHREADS
|
||||||
|
#define WOLFSSL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef WOLFSSL_NO_ATOMICS
|
#ifndef WOLFSSL_NO_ATOMICS
|
||||||
#ifdef HAVE_C___ATOMIC
|
#ifdef HAVE_C___ATOMIC
|
||||||
|
Reference in New Issue
Block a user