Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions wolfssl/wolfcrypt/mem_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ static memoryStats ourMemStats;
WOLFSSL_API extern memoryStats *wc_MemStats_Ptr;

#ifdef DO_MEM_LIST
#include <pthread.h>
static memoryList ourMemList;
static pthread_mutex_t memLock = PTHREAD_MUTEX_INITIALIZER;
static wolfSSL_Mutex memLock WOLFSSL_MUTEX_INITIALIZER_CLAUSE(memLock);
#endif
Comment thread
dgarske marked this conversation as resolved.

#ifdef WOLFSSL_DEBUG_MEMORY
Expand Down Expand Up @@ -182,7 +181,7 @@ static WC_INLINE void* TrackMalloc(size_t sz)
#endif
#endif
#if !defined(SINGLE_THREADED) && (defined(DO_MEM_LIST) || defined(DO_MEM_STATS))
if (pthread_mutex_lock(&memLock) == 0)
if (wc_LockMutex(&memLock) == 0)
{
Comment on lines +184 to 185
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On platforms where WOLFSSL_MUTEX_INITIALIZER is not available, memLock is only initialized in InitMemoryTracker(), but TrackMalloc()/TrackFree()/ShowMemoryTracker() can attempt to lock it regardless. This is a regression versus the previous statically-initialized pthread_mutex_t and can lead to locking an uninitialized mutex. Fix by ensuring the mutex is initialized before any lock attempt (e.g., lazy one-time init in the locking path, or guaranteeing initialization before installing/using the tracking allocators).

Copilot uses AI. Check for mistakes.
#endif

Expand Down Expand Up @@ -228,7 +227,7 @@ static WC_INLINE void* TrackMalloc(size_t sz)
ourMemList.count++;
#endif
#if !defined(SINGLE_THREADED) && (defined(DO_MEM_LIST) || defined(DO_MEM_STATS))
pthread_mutex_unlock(&memLock);
wc_UnLockMutex(&memLock);
}
#endif /* DO_MEM_LIST */

Expand All @@ -255,7 +254,7 @@ static WC_INLINE void TrackFree(void* ptr)
sz = header->thisSize;

#if !defined(SINGLE_THREADED) && (defined(DO_MEM_LIST) || defined(DO_MEM_STATS))
if (pthread_mutex_lock(&memLock) == 0)
if (wc_LockMutex(&memLock) == 0)
{
#endif

Expand Down Expand Up @@ -289,7 +288,7 @@ static WC_INLINE void TrackFree(void* ptr)
#endif

#if !defined(SINGLE_THREADED) && (defined(DO_MEM_LIST) || defined(DO_MEM_STATS))
pthread_mutex_unlock(&memLock);
wc_UnLockMutex(&memLock);
}
#endif

Expand Down Expand Up @@ -369,7 +368,10 @@ static WC_INLINE int InitMemoryTracker(void)
}

#ifdef DO_MEM_LIST
if (pthread_mutex_lock(&memLock) == 0)
#ifndef WOLFSSL_MUTEX_INITIALIZER
wc_InitMutex(&memLock);
#endif
if (wc_LockMutex(&memLock) == 0)
Comment on lines +371 to +374
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wc_InitMutex(&memLock) is called without checking its return value, and it may be called multiple times if InitMemoryTracker() can be invoked more than once (double-init / resource leak risk depending on the platform implementation). Consider guarding initialization with a static 'initialized' flag and handling wc_InitMutex failures (e.g., returning an error from InitMemoryTracker() when initialization fails).

Copilot uses AI. Check for mistakes.
#endif
{
#ifdef DO_MEM_STATS
Expand All @@ -388,7 +390,7 @@ static WC_INLINE int InitMemoryTracker(void)
XMEMSET(&ourMemList, 0, sizeof(ourMemList));
ourMemStats.memList = &ourMemList;

pthread_mutex_unlock(&memLock);
wc_UnLockMutex(&memLock);
#endif
}

Expand All @@ -400,7 +402,7 @@ static WC_INLINE int InitMemoryTracker(void)
static WC_INLINE void ShowMemoryTracker(void)
{
#ifdef DO_MEM_LIST
if (pthread_mutex_lock(&memLock) == 0)
if (wc_LockMutex(&memLock) == 0)
#endif
{
#ifdef DO_MEM_STATS
Expand Down Expand Up @@ -430,13 +432,16 @@ static WC_INLINE void ShowMemoryTracker(void)
}
}

pthread_mutex_unlock(&memLock);
wc_UnLockMutex(&memLock);
#endif
}
}

static WC_INLINE int CleanupMemoryTracker(void)
{
#ifndef WOLFSSL_MUTEX_INITIALIZER
wc_FreeMutex(&memLock);
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wc_FreeMutex(&memLock) is unconditional (when WOLFSSL_MUTEX_INITIALIZER is not defined) but there’s no guarantee the mutex was successfully initialized (or initialized at all, if cleanup can run without prior init). Consider freeing only when initialization succeeded (e.g., via an initialization flag set after a successful wc_InitMutex).

Suggested change
wc_FreeMutex(&memLock);
if (wc_MemStats_Ptr != NULL) {
wc_FreeMutex(&memLock);
}

Copilot uses AI. Check for mistakes.
#endif
wc_MemStats_Ptr = NULL;
/* restore default allocators */
return wolfSSL_SetAllocators(mfDefault, ffDefault, rfDefault);
Expand Down
18 changes: 7 additions & 11 deletions wolfssl/wolfcrypt/wc_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,12 @@
* before Zephyr's posix_types.h can define a conflicting timer_t */
#include <sys/types.h>
#ifndef SINGLE_THREADED
#if !defined(CONFIG_PTHREAD_IPC) && !defined(CONFIG_POSIX_THREADS)
#error "Threading needs CONFIG_PTHREAD_IPC / CONFIG_POSIX_THREADS"
#endif
#if KERNEL_VERSION_NUMBER >= 0x30100
#include <zephyr/kernel.h>
#ifndef CONFIG_ARCH_POSIX
#include <zephyr/posix/posix_types.h>
#include <zephyr/posix/pthread.h>
#endif
#else
#if !defined(CONFIG_PTHREAD_IPC) && !defined(CONFIG_POSIX_THREADS)
#error "Threading needs CONFIG_PTHREAD_IPC / CONFIG_POSIX_THREADS"
#endif
#include <kernel.h>
#ifndef CONFIG_ARCH_POSIX
#include <posix/posix_types.h>
Expand Down Expand Up @@ -1557,12 +1553,12 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void);
#include <posix/time.h>
#endif

#ifndef CLOCK_REALTIME
#ifdef SYS_CLOCK_REALTIME
#ifdef SYS_CLOCK_REALTIME
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME SYS_CLOCK_REALTIME
#define clock_gettime sys_clock_gettime
#define clock_settime sys_clock_settime
#endif
#define clock_gettime sys_clock_gettime
#define clock_settime sys_clock_settime
Comment on lines 1559 to +1561
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping clock_gettime/clock_settime unconditionally when SYS_CLOCK_REALTIME is defined can break builds when a libc already provides clock_gettime (e.g., macro/function redefinition or signature mismatch). Consider only defining these aliases when clock_gettime/clock_settime are not already provided (or when CLOCK_REALTIME is missing), mirroring the previous guard behavior.

Suggested change
#endif
#define clock_gettime sys_clock_gettime
#define clock_settime sys_clock_settime
#define clock_gettime sys_clock_gettime
#define clock_settime sys_clock_settime
#endif

Copilot uses AI. Check for mistakes.
#endif

#if defined(CONFIG_RTC)
Expand Down
Loading