From 64e4796ed6dcac0e26ef54b1c4d34b69f89551c6 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 14 Dec 2023 13:21:27 -0600 Subject: [PATCH] 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. --- src/ssl.c | 53 +++++++++++++++++++++++++------------ wolfssl/wolfcrypt/wc_port.h | 3 +++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 64bddbea0..cf4ab9fbf 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1265,8 +1265,12 @@ int wolfSSL_send_session(WOLFSSL* ssl) /* prevent multiple mutex initializations */ 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 int count_mutex_valid = 0; +#endif /* Create a new WOLFSSL_CTX struct and return the pointer to created struct. WOLFSSL_METHOD pointer passed in is given to ctx to manage. @@ -6258,6 +6262,7 @@ int wolfSSL_Init(void) } #endif #endif +#ifndef WOLFSSL_MUTEX_INITIALIZER if (ret == WOLFSSL_SUCCESS) { if (wc_InitMutex(&count_mutex) != 0) { WOLFSSL_MSG("Bad Init Mutex count"); @@ -6267,6 +6272,7 @@ int wolfSSL_Init(void) count_mutex_valid = 1; } } +#endif /* !WOLFSSL_MUTEX_INITIALIZER */ #if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT) /* OpenSSL registers cleanup using atexit */ if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) { @@ -13378,21 +13384,30 @@ int wolfSSL_Cleanup(void) WOLFSSL_ENTER("wolfSSL_Cleanup"); - if (initRefCount == 0) - 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; - +#ifndef WOLFSSL_MUTEX_INITIALIZER 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) return ret; @@ -13442,11 +13457,13 @@ int wolfSSL_Cleanup(void) #endif #endif /* !NO_SESSION_CACHE */ +#ifndef WOLFSSL_MUTEX_INITIALIZER if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) { if (ret == WOLFSSL_SUCCESS) ret = BAD_MUTEX_E; } count_mutex_valid = 0; +#endif #ifdef OPENSSL_EXTRA wolfSSL_RAND_Cleanup(); @@ -14339,6 +14356,8 @@ ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverI { int error = -1; word32 clientRow = 0, clientIdx = 0; + ClientSession* ret = NULL; + (void)useTicket; if (side == WOLFSSL_CLIENT_END && 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; } + ret = &ClientCache[clientRow].Clients[clientIdx]; + wc_UnLockMutex(&clisession_mutex); } else { @@ -14402,10 +14423,8 @@ ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverI else { WOLFSSL_MSG("Skipping client cache"); } - if (error == 0) - return &ClientCache[clientRow].Clients[clientIdx]; - else - return NULL; + + return ret; } #endif /* !NO_CLIENT_CACHE */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 35bfb2b95..0a06378fc 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -307,6 +307,9 @@ #if !defined(WOLFSSL_USE_RWLOCK) || defined(SINGLE_THREADED) typedef wolfSSL_Mutex wolfSSL_RwLock; #endif +#ifdef WOLFSSL_PTHREADS + #define WOLFSSL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#endif #ifndef WOLFSSL_NO_ATOMICS #ifdef HAVE_C___ATOMIC