forked from wolfSSL/wolfssl
src/ssl.c: implement WOLFSSL_CLEANUP_THREADSAFE in wolfSSL_Init() / wolfSSL_Cleanup().
This commit is contained in:
57
src/ssl.c
57
src/ssl.c
@@ -1037,7 +1037,7 @@ static volatile WOLFSSL_GLOBAL int initRefCount = 0;
|
|||||||
static WOLFSSL_GLOBAL wolfSSL_Mutex inits_count_mutex
|
static WOLFSSL_GLOBAL wolfSSL_Mutex inits_count_mutex
|
||||||
WOLFSSL_MUTEX_INITIALIZER_CLAUSE(inits_count_mutex);
|
WOLFSSL_MUTEX_INITIALIZER_CLAUSE(inits_count_mutex);
|
||||||
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
static WOLFSSL_GLOBAL int inits_count_mutex_valid = 0;
|
static WOLFSSL_GLOBAL volatile int inits_count_mutex_valid = 0;
|
||||||
#endif
|
#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.
|
||||||
@@ -5641,12 +5641,29 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
|||||||
static int wolfSSL_RAND_InitMutex(void);
|
static int wolfSSL_RAND_InitMutex(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_CLEANUP_THREADSAFE) && !defined(WOLFSSL_MUTEX_INITIALIZER)
|
||||||
|
#ifndef WOLFSSL_ATOMIC_OPS
|
||||||
|
#error WOLFSSL_CLEANUP_THREADSAFE with !WOLFSSL_MUTEX_INITIALIZER requires WOLFSSL_ATOMIC_OPS
|
||||||
|
#endif
|
||||||
|
/* WOLFSSL_CLEANUP_THREADSAFE depends on a wolfSSL_Atomic_Int that can
|
||||||
|
* be statically initialized.
|
||||||
|
*/
|
||||||
|
static wolfSSL_Atomic_Int inits_count_mutex_valid2 = 0;
|
||||||
|
#endif /* WOLFSSL_CLEANUP_THREADSAFE && !WOLFSSL_MUTEX_INITIALIZER */
|
||||||
|
|
||||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
|
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
|
||||||
static void AtExitCleanup(void)
|
static void AtExitCleanup(void)
|
||||||
{
|
{
|
||||||
if (initRefCount > 0) {
|
if (initRefCount > 0) {
|
||||||
initRefCount = 1;
|
initRefCount = 1;
|
||||||
(void)wolfSSL_Cleanup();
|
(void)wolfSSL_Cleanup();
|
||||||
|
#if defined(WOLFSSL_CLEANUP_THREADSAFE) && !defined(WOLFSSL_MUTEX_INITIALIZER)
|
||||||
|
if (inits_count_mutex_valid == 1) {
|
||||||
|
(void)wc_FreeMutex(&inits_count_mutex);
|
||||||
|
inits_count_mutex_valid = 0;
|
||||||
|
inits_count_mutex_valid2 = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -5662,13 +5679,37 @@ int wolfSSL_Init(void)
|
|||||||
WOLFSSL_ENTER("wolfSSL_Init");
|
WOLFSSL_ENTER("wolfSSL_Init");
|
||||||
|
|
||||||
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
||||||
if (inits_count_mutex_valid == 0) {
|
if (inits_count_mutex_valid <= 0) {
|
||||||
if (wc_InitMutex(&inits_count_mutex) != 0) {
|
#ifdef WOLFSSL_CLEANUP_THREADSAFE
|
||||||
WOLFSSL_MSG("Bad Init Mutex count");
|
int current_inits_count_mutex_valid;
|
||||||
return BAD_MUTEX_E;
|
if (wolfSSL_Atomic_Int_FetchAdd(&inits_count_mutex_valid2, 1) != 0) {
|
||||||
|
/* We treat inits_count_mutex_valid as a spin lock -- this may cause
|
||||||
|
* deadlocks in some runtimes. Applications can fully mitigate this
|
||||||
|
* race by calling wolfSSL_Init() and wolfSSL_Cleanup()
|
||||||
|
* consecutively at startup, uncontended. This leaves
|
||||||
|
* inits_count_mutex safely initialized, but releases all other
|
||||||
|
* resources.
|
||||||
|
*/
|
||||||
|
while ((current_inits_count_mutex_valid = inits_count_mutex_valid) == 0);
|
||||||
|
if (current_inits_count_mutex_valid < 0) {
|
||||||
|
(void)wolfSSL_Atomic_Int_FetchSub(&inits_count_mutex_valid2, 1);
|
||||||
|
return BAD_MUTEX_E;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
inits_count_mutex_valid = 1;
|
#endif /* WOLFSSL_CLEANUP_THREADSAFE */
|
||||||
|
{
|
||||||
|
if (wc_InitMutex(&inits_count_mutex) != 0) {
|
||||||
|
WOLFSSL_MSG("Bad Init Mutex count");
|
||||||
|
inits_count_mutex_valid = -1;
|
||||||
|
#ifdef WOLFSSL_CLEANUP_THREADSAFE
|
||||||
|
(void)wolfSSL_Atomic_Int_FetchSub(&inits_count_mutex_valid2, 1);
|
||||||
|
#endif
|
||||||
|
return BAD_MUTEX_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inits_count_mutex_valid = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !WOLFSSL_MUTEX_INITIALIZER */
|
#endif /* !WOLFSSL_MUTEX_INITIALIZER */
|
||||||
@@ -10422,7 +10463,7 @@ int wolfSSL_Cleanup(void)
|
|||||||
#endif
|
#endif
|
||||||
#endif /* !NO_SESSION_CACHE */
|
#endif /* !NO_SESSION_CACHE */
|
||||||
|
|
||||||
#ifndef WOLFSSL_MUTEX_INITIALIZER
|
#if !defined(WOLFSSL_CLEANUP_THREADSAFE) && !defined(WOLFSSL_MUTEX_INITIALIZER)
|
||||||
if ((inits_count_mutex_valid == 1) &&
|
if ((inits_count_mutex_valid == 1) &&
|
||||||
(wc_FreeMutex(&inits_count_mutex) != 0)) {
|
(wc_FreeMutex(&inits_count_mutex) != 0)) {
|
||||||
if (ret == WOLFSSL_SUCCESS)
|
if (ret == WOLFSSL_SUCCESS)
|
||||||
|
@@ -320,6 +320,10 @@
|
|||||||
|
|
||||||
#endif /* SINGLE_THREADED */
|
#endif /* SINGLE_THREADED */
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_TEST_NO_MUTEX_INITIALIZER
|
||||||
|
#undef WOLFSSL_MUTEX_INITIALIZER
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_MUTEX_INITIALIZER
|
#ifdef WOLFSSL_MUTEX_INITIALIZER
|
||||||
#define WOLFSSL_MUTEX_INITIALIZER_CLAUSE(lockname) = WOLFSSL_MUTEX_INITIALIZER(lockname)
|
#define WOLFSSL_MUTEX_INITIALIZER_CLAUSE(lockname) = WOLFSSL_MUTEX_INITIALIZER(lockname)
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user