Skip to content

Commit

Permalink
add struct wolfSSL_RefWithMutex, wolfSSL_RefWithMutexLock, and wolfSS…
Browse files Browse the repository at this point in the history
…L_RefWithMutexUnlock, and change WOLFSSL_CTX.ref from wolfSSL_Ref to wolfSSL_RefWithMutex.

in in wc_port.c, rename mutexful implementations of wolfSSL_Ref*() to wolfSSL_RefWithMutex*(), and build them even if defined(WOLFSSL_ATOMIC_OPS).

refactor wolfSSL_CTX_UnloadIntermediateCerts() to wrap the refcount check and deallocation with wolfSSL_RefWithMutexLock()...wolfSSL_RefWithMutexUnlock().

move port-specific setup for WARN_UNUSED_RESULT, WC_MAYBE_UNUSED, and WC_INLINE, from types.h to wc_port.h, to make them usable by port-specific definitions later in wc_port.h.

when defined(SINGLE_THREADED) and !defined(WOLFSSL_NO_ATOMICS), typedef int wolfSSL_Atomic_Int, so that access to wolfSSL_Atomic_Ints in SINGLE_THREADED builds is easy.

refactor fallback definitions of wolfSSL_Atomic_Int_FetchAdd and wolfSSL_Atomic_Int_FetchSub as WC_INLINE functions to avoid -Wunused-result.
  • Loading branch information
douzzer committed Nov 15, 2024
1 parent e1116e8 commit 595f55e
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 87 deletions.
4 changes: 2 additions & 2 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2297,7 +2297,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap)
ctx->minDowngrade = WOLFSSL_MIN_DOWNGRADE;
}

wolfSSL_RefInit(&ctx->ref, &ret);
wolfSSL_RefWithMutexInit(&ctx->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret < 0) {
WOLFSSL_MSG("Mutex error on CTX init");
Expand Down Expand Up @@ -2782,7 +2782,7 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx)
#endif

/* decrement CTX reference count */
wolfSSL_RefDec(&ctx->ref, &isZero, &ret);
wolfSSL_RefWithMutexDec(&ctx->ref, &isZero, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret < 0) {
/* check error state, if mutex error code then mutex init failed but
Expand Down
19 changes: 15 additions & 4 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
{
int ret;
wolfSSL_RefInc(&ctx->ref, &ret);
wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
#else
Expand Down Expand Up @@ -11104,18 +11104,29 @@ int wolfSSL_set_compression(WOLFSSL* ssl)

int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
{
int ret;

WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");

if (ctx == NULL)
return BAD_FUNC_ARG;

ret = wolfSSL_RefWithMutexLock(&ctx->ref);
if (ret < 0)
return ret;

if (ctx->ref.count > 1) {
WOLFSSL_MSG("ctx object must have a ref count of 1 before "
"unloading intermediate certs");
return BAD_STATE_E;
ret = BAD_STATE_E;
}
else {
ret = wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
}

return wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
wolfSSL_RefWithMutexUnlock(&ctx->ref);

return ret;
}


Expand Down Expand Up @@ -20579,7 +20590,7 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
InitSSL_CTX_Suites(ctx);
}

wolfSSL_RefInc(&ctx->ref, &ret);
wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
if (ret != 0) {
/* can only fail on serious stuff, like mutex not working
Expand Down
25 changes: 18 additions & 7 deletions wolfcrypt/src/wc_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ char* wc_strdup_ex(const char *src, int memType) {
}
#endif

#ifdef WOLFSSL_ATOMIC_OPS
#if defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED)

#ifdef HAVE_C___ATOMIC
/* Atomic ops using standard C lib */
Expand Down Expand Up @@ -1292,8 +1292,9 @@ int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i)

#endif /* WOLFSSL_ATOMIC_OPS */

#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
#if !defined(SINGLE_THREADED)

void wolfSSL_RefWithMutexInit(wolfSSL_RefWithMutex* ref, int* err)
{
int ret = wc_InitMutex(&ref->mutex);
if (ret != 0) {
Expand All @@ -1304,14 +1305,14 @@ void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err)
*err = ret;
}

void wolfSSL_RefFree(wolfSSL_Ref* ref)
void wolfSSL_RefWithMutexFree(wolfSSL_RefWithMutex* ref)
{
if (wc_FreeMutex(&ref->mutex) != 0) {
WOLFSSL_MSG("Failed to free mutex of reference counting!");
}
}

void wolfSSL_RefInc(wolfSSL_Ref* ref, int* err)
void wolfSSL_RefWithMutexInc(wolfSSL_RefWithMutex* ref, int* err)
{
int ret = wc_LockMutex(&ref->mutex);
if (ret != 0) {
Expand All @@ -1324,7 +1325,17 @@ void wolfSSL_RefInc(wolfSSL_Ref* ref, int* err)
*err = ret;
}

void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err)
int wolfSSL_RefWithMutexLock(wolfSSL_RefWithMutex* ref)
{
return wc_LockMutex(&ref->mutex);
}

void wolfSSL_RefWithMutexUnlock(wolfSSL_RefWithMutex* ref)
{
wc_UnLockMutex(&ref->mutex);
}

void wolfSSL_RefWithMutexDec(wolfSSL_RefWithMutex* ref, int* isZero, int* err)
{
int ret = wc_LockMutex(&ref->mutex);
if (ret != 0) {
Expand All @@ -1341,7 +1352,7 @@ void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err)
}
*err = ret;
}
#endif
#endif /* ! SINGLE_THREADED */

#if WOLFSSL_CRYPT_HW_MUTEX
/* Mutex for protection of cryptography hardware */
Expand Down
2 changes: 1 addition & 1 deletion wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3724,7 +3724,7 @@ struct WOLFSSL_CTX {
#ifdef SINGLE_THREADED
WC_RNG* rng; /* to be shared with WOLFSSL w/o locking */
#endif
wolfSSL_Ref ref;
wolfSSL_RefWithMutex ref;
int err; /* error code in case of mutex not created */
#ifndef NO_DH
buffer serverDH_P;
Expand Down
56 changes: 0 additions & 56 deletions wolfssl/wolfcrypt/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,25 +318,6 @@ typedef struct w64wrapper {
#define WOLFSSL_MAX_16BIT 0xffffU
#define WOLFSSL_MAX_32BIT 0xffffffffU

#ifndef WARN_UNUSED_RESULT
#if defined(WOLFSSL_LINUXKM) && defined(__must_check)
#define WARN_UNUSED_RESULT __must_check
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || \
(defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001))
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#endif /* WARN_UNUSED_RESULT */

#ifndef WC_MAYBE_UNUSED
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) || defined(__IAR_SYSTEMS_ICC__)
#define WC_MAYBE_UNUSED __attribute__((unused))
#else
#define WC_MAYBE_UNUSED
#endif
#endif /* WC_MAYBE_UNUSED */

#ifndef WC_DO_NOTHING
#define WC_DO_NOTHING do {} while (0)
#ifdef _MSC_VER
Expand All @@ -347,43 +328,6 @@ typedef struct w64wrapper {
#endif
#endif

/* use inlining if compiler allows */
#ifndef WC_INLINE
#ifndef NO_INLINE
#ifdef _MSC_VER
#define WC_INLINE __inline
#elif defined(__GNUC__)
#ifdef WOLFSSL_VXWORKS
#define WC_INLINE __inline__
#else
#define WC_INLINE inline
#endif
#elif defined(__IAR_SYSTEMS_ICC__)
#define WC_INLINE inline
#elif defined(THREADX)
#define WC_INLINE _Inline
#elif defined(__ghc__)
#ifndef __cplusplus
#define WC_INLINE __inline
#else
#define WC_INLINE inline
#endif
#elif defined(__CCRX__)
#define WC_INLINE inline
#elif defined(__DCC__)
#ifndef __cplusplus
#define WC_INLINE __inline__
#else
#define WC_INLINE inline
#endif
#else
#define WC_INLINE WC_MAYBE_UNUSED
#endif
#else
#define WC_INLINE WC_MAYBE_UNUSED
#endif
#endif

#if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
#define INLINE WC_INLINE
#endif
Expand Down
131 changes: 114 additions & 17 deletions wolfssl/wolfcrypt/wc_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,63 @@
#include "../../linuxkm/linuxkm_wc_port.h"
#endif /* WOLFSSL_LINUXKM */

#ifndef WARN_UNUSED_RESULT
#if defined(WOLFSSL_LINUXKM) && defined(__must_check)
#define WARN_UNUSED_RESULT __must_check
#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || \
(defined(__IAR_SYSTEMS_ICC__) && (__VER__ >= 9040001))
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#endif /* !WARN_UNUSED_RESULT */

#ifndef WC_MAYBE_UNUSED
#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) || \
defined(__IAR_SYSTEMS_ICC__)
#define WC_MAYBE_UNUSED __attribute__((unused))
#else
#define WC_MAYBE_UNUSED
#endif
#endif /* !WC_MAYBE_UNUSED */

/* use inlining if compiler allows */
#ifndef WC_INLINE
#ifndef NO_INLINE
#ifdef _MSC_VER
#define WC_INLINE __inline
#elif defined(__GNUC__)
#ifdef WOLFSSL_VXWORKS
#define WC_INLINE __inline__
#else
#define WC_INLINE inline
#endif
#elif defined(__IAR_SYSTEMS_ICC__)
#define WC_INLINE inline
#elif defined(THREADX)
#define WC_INLINE _Inline
#elif defined(__ghc__)
#ifndef __cplusplus
#define WC_INLINE __inline
#else
#define WC_INLINE inline
#endif
#elif defined(__CCRX__)
#define WC_INLINE inline
#elif defined(__DCC__)
#ifndef __cplusplus
#define WC_INLINE __inline__
#else
#define WC_INLINE inline
#endif
#else
#define WC_INLINE WC_MAYBE_UNUSED
#endif
#else
#define WC_INLINE WC_MAYBE_UNUSED
#endif
#endif

/* THREADING/MUTEX SECTION */
#if defined(SINGLE_THREADED) && defined(NO_FILESYSTEM)
/* No system headers required for build. */
Expand Down Expand Up @@ -335,7 +392,11 @@
#endif

#ifndef WOLFSSL_NO_ATOMICS
#ifdef HAVE_C___ATOMIC
#ifdef SINGLE_THREADED
typedef int wolfSSL_Atomic_Int;
#define WOLFSSL_ATOMIC_INITIALIZER(x) (x)
#define WOLFSSL_ATOMIC_OPS
#elif defined(HAVE_C___ATOMIC)
#ifdef __cplusplus
#if defined(__GNUC__) && defined(__ATOMIC_RELAXED)
/* C++ using direct calls to compiler built-in functions */
Expand Down Expand Up @@ -365,34 +426,47 @@
#endif
#endif /* WOLFSSL_NO_ATOMICS */

#ifdef WOLFSSL_ATOMIC_OPS
#if defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED)
WOLFSSL_API void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i);
/* Fetch* functions return the value of the counter immediately preceding
* the effects of the function. */
WOLFSSL_API int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i);
#else
/* Code using these fallback macros needs to arrange its own fallback for
* wolfSSL_Atomic_Int, which is never defined if
* !defined(WOLFSSL_ATOMIC_OPS). This forces local awareness of
* thread-unsafe semantics.
/* Code using these fallback implementations in non-SINGLE_THREADED builds
* needs to arrange its own explicit fallback to int for wolfSSL_Atomic_Int,
* which is not defined if !defined(WOLFSSL_ATOMIC_OPS) &&
* !defined(SINGLE_THREADED). This forces local awareness of thread-unsafe
* semantics.
*/
#define wolfSSL_Atomic_Int_Init(c, i) (*(c) = (i))
#define wolfSSL_Atomic_Int_FetchAdd(c, i) (*(c) += (i), *(c) - (i))
#define wolfSSL_Atomic_Int_FetchSub(c, i) (*(c) -= (i), *(c) + (i))
static WC_INLINE int wolfSSL_Atomic_Int_FetchAdd(int *c, int i) {
int ret = *c;
*c += i;
return ret;
}
static WC_INLINE int wolfSSL_Atomic_Int_FetchSub(int *c, int i) {
int ret = *c;
*c -= i;
return ret;
}
#endif

/* Reference counting. */
typedef struct wolfSSL_Ref {
#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_ATOMIC_OPS)
typedef struct wolfSSL_RefWithMutex {
#if !defined(SINGLE_THREADED)
wolfSSL_Mutex mutex;
#endif
#ifdef WOLFSSL_ATOMIC_OPS
int count;
} wolfSSL_RefWithMutex;

#if defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED)
typedef struct wolfSSL_Ref {
wolfSSL_Atomic_Int count;
} wolfSSL_Ref;
#else
int count;
typedef struct wolfSSL_RefWithMutex wolfSSL_Ref;
#endif
} wolfSSL_Ref;

#if defined(SINGLE_THREADED) || defined(WOLFSSL_ATOMIC_OPS)

Expand All @@ -419,10 +493,33 @@ typedef struct wolfSSL_Ref {

#define WOLFSSL_REFCNT_ERROR_RETURN

WOLFSSL_LOCAL void wolfSSL_RefInit(wolfSSL_Ref* ref, int* err);
WOLFSSL_LOCAL void wolfSSL_RefFree(wolfSSL_Ref* ref);
WOLFSSL_LOCAL void wolfSSL_RefInc(wolfSSL_Ref* ref, int* err);
WOLFSSL_LOCAL void wolfSSL_RefDec(wolfSSL_Ref* ref, int* isZero, int* err);
#define wolfSSL_RefInit wolfSSL_RefWithMutexInit
#define wolfSSL_RefFree wolfSSL_RefWithMutexFree
#define wolfSSL_RefInc wolfSSL_RefWithMutexInc
#define wolfSSL_RefDec wolfSSL_RefWithMutexDec

#endif

#if defined(SINGLE_THREADED)

#define wolfSSL_RefWithMutexInit wolfSSL_RefInit
#define wolfSSL_RefWithMutexFree wolfSSL_RefFree
#define wolfSSL_RefWithMutexInc wolfSSL_RefInc
#define wolfSSL_RefWithMutexLock(ref) 0
#define wolfSSL_RefWithMutexUnlock(ref) WC_DO_NOTHING
#define wolfSSL_RefWithMutexDec wolfSSL_RefDec

#else

WOLFSSL_LOCAL void wolfSSL_RefWithMutexInit(wolfSSL_RefWithMutex* ref,
int* err);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexFree(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexInc(wolfSSL_RefWithMutex* ref,
int* err);
WOLFSSL_LOCAL int wolfSSL_RefWithMutexLock(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexUnlock(wolfSSL_RefWithMutex* ref);
WOLFSSL_LOCAL void wolfSSL_RefWithMutexDec(wolfSSL_RefWithMutex* ref,
int* isZero, int* err);

#endif

Expand Down

0 comments on commit 595f55e

Please sign in to comment.