Skip to content

Commit

Permalink
Merge pull request #7846 from douzzer/20240806-debug-trace-errcodes-b…
Browse files Browse the repository at this point in the history
…acktrace

20240806-debug-trace-errcodes-backtrace
  • Loading branch information
SparkiDev authored Aug 8, 2024
2 parents 0ab1f19 + c25d86c commit 2a08d30
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 38 deletions.
10 changes: 8 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,17 @@ AC_ARG_ENABLE([debug-trace-errcodes],
[ ENABLED_DEBUG_TRACE_ERRCODES=no ]
)

if test "$ENABLED_DEBUG_TRACE_ERRCODES" = "yes"
if test "$ENABLED_DEBUG_TRACE_ERRCODES" != "no"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DEBUG_TRACE_ERROR_CODES"
fi

if test "$ENABLED_DEBUG_TRACE_ERRCODES" = "backtrace"
then
AM_CFLAGS="$AM_CFLAGS -g -funwind-tables -DWOLFSSL_DEBUG_BACKTRACE_ERROR_CODES"
AM_LDFLAGS="$AM_LDFLAGS -lbacktrace"
fi

# Start without certificates enabled and enable if a certificate algorithm is
# enabled
ENABLED_CERTS="no"
Expand Down Expand Up @@ -9981,7 +9987,7 @@ echo "" >> $OPTION_FILE
echo "#endif /* WOLFSSL_OPTIONS_H */" >> $OPTION_FILE
echo "" >> $OPTION_FILE
if test "$ENABLED_DEBUG_TRACE_ERRCODES" = "yes"
if test "$ENABLED_DEBUG_TRACE_ERRCODES" != "no"
then
support/gen-debug-trace-error-codes.sh || AC_MSG_ERROR([Header generation for debug-trace-errcodes failed.])
fi
Expand Down
6 changes: 5 additions & 1 deletion src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -20653,7 +20653,11 @@ static void LogAlert(int type)
typeStr = AlertTypeToString(type);
if (typeStr != NULL) {
char buff[60];
XSNPRINTF(buff, sizeof(buff), "Alert type: %s", typeStr);
if (XSNPRINTF(buff, sizeof(buff), "Alert type: %s", typeStr)
>= (int)sizeof(buff))
{
buff[sizeof(buff) - 1] = 0;
}
WOLFSSL_MSG(buff);
}
#else
Expand Down
4 changes: 3 additions & 1 deletion src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -4691,7 +4691,9 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa)
mp_clear(t);

#ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, rsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (rsa != NULL) {
XFREE(tmp, rsa->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif

return ret;
Expand Down
7 changes: 6 additions & 1 deletion support/gen-debug-trace-error-codes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ BEGIN {
print("#undef WOLFSSL_DEBUG_TRACE_ERROR_CODES_H") >> "wolfssl/debug-untrace-error-codes.h";
}
{
if (match($0, "^[[:space:]]+([A-Z][A-Z0-9_]+)[[:space:]]*=[[:space:]]*(-[0-9]+)[,[:space:]]", errcode_a)) {
if (match($0, "^[[:space:]]+([A-Z][A-Z0-9_]+)[[:space:]]*=[[:space:]]*(-[0-9]+)[,[:space:]]")) {
# for mawkward compatibility -- gawk allows errcode_a as the 3rd arg to match().
gsub("^[[:space:]]+", "", $0);
split($0, errcode_a, "[[:space:]=,]+");
if ((errcode_a[1] == "MIN_CODE_E") ||
(errcode_a[1] == "WC_LAST_E") ||
(errcode_a[1] == "MAX_CODE_E"))
Expand Down
8 changes: 5 additions & 3 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -78089,9 +78089,11 @@ static int load_pem_key_file_as_der(const char* privKeyFile, DerBuffer** pDer,
(void)encInfo; /* not used in this test */

#ifdef DEBUG_WOLFSSL
fprintf(stderr, "%s (%d): Loading PEM %s (len %d) to DER (len %d)\n",
(ret == 0) ? "Success" : "Failure", ret, privKeyFile, (int)key_sz,
(*pDer)->length);
if (*pDer != NULL) {
fprintf(stderr, "%s (%d): Loading PEM %s (len %d) to DER (len %d)\n",
(ret == 0) ? "Success" : "Failure", ret, privKeyFile,
(int)key_sz, (*pDer)->length);
}
#endif

return ret;
Expand Down
12 changes: 0 additions & 12 deletions wolfcrypt/benchmark/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -1663,18 +1663,6 @@ static const char* bench_result_words3[][5] = {
const char *desc_extra);
#endif

#if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND) && \
!defined(HAVE_STACK_SIZE)
#ifdef __cplusplus
extern "C" {
#endif
WOLFSSL_API int wolfSSL_Debugging_ON(void);
WOLFSSL_API void wolfSSL_Debugging_OFF(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

#if !defined(WC_NO_RNG) && \
((!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) \
|| !defined(NO_DH) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \
Expand Down
200 changes: 188 additions & 12 deletions wolfcrypt/src/logging.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,26 +471,48 @@ void WOLFSSL_BUFFER(const byte* buffer, word32 length)

while (buflen > 0) {
int bufidx = 0;
XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "\t");
if (XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "\t")
>= (int)sizeof(line) - bufidx)
{
goto errout;
}
bufidx++;

for (i = 0; i < LINE_LEN; i++) {
if (i < buflen) {
XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "%02x ", buffer[i]);
if (XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "%02x ",
buffer[i]) >= (int)sizeof(line) - bufidx)
{
goto errout;
}
}
else {
XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, " ");
if (XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, " ")
>= (int)sizeof(line) - bufidx)
{
goto errout;
}
}
bufidx += 3;
}

XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "| ");
if (XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "| ")
>= (int)sizeof(line) - bufidx)
{
goto errout;
}
bufidx++;

for (i = 0; i < LINE_LEN; i++) {
if (i < buflen) {
XSNPRINTF(&line[bufidx], sizeof(line)-bufidx,
"%c", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.');
if (XSNPRINTF(&line[bufidx], sizeof(line)-bufidx,
"%c", 31 < buffer[i] && buffer[i] < 127
? buffer[i]
: '.')
>= (int)sizeof(line) - bufidx)
{
goto errout;
}
bufidx++;
}
}
Expand All @@ -499,14 +521,24 @@ void WOLFSSL_BUFFER(const byte* buffer, word32 length)
buffer += LINE_LEN;
buflen -= LINE_LEN;
}

return;

errout:

wolfssl_log(INFO_LOG, NULL, 0, "\t[Buffer error while rendering]");
}

#undef WOLFSSL_ENTER /* undo WOLFSSL_DEBUG_CODEPOINTS wrapper */
void WOLFSSL_ENTER(const char* msg)
{
if (loggingEnabled) {
char buffer[WOLFSSL_MAX_ERROR_SZ];
XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
if (XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg)
>= (int)sizeof(buffer))
{
buffer[sizeof(buffer) - 1] = 0;
}
wolfssl_log(ENTER_LOG, NULL, 0, buffer);
}
}
Expand All @@ -516,7 +548,11 @@ void WOLFSSL_ENTER2(const char *file, int line, const char* msg)
{
if (loggingEnabled) {
char buffer[WOLFSSL_MAX_ERROR_SZ];
XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
if (XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg)
>= (int)sizeof(buffer))
{
buffer[sizeof(buffer) - 1] = 0;
}
wolfssl_log(ENTER_LOG, file, line, buffer);
}
}
Expand All @@ -527,8 +563,12 @@ void WOLFSSL_LEAVE(const char* msg, int ret)
{
if (loggingEnabled) {
char buffer[WOLFSSL_MAX_ERROR_SZ];
XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
msg, ret);
if (XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
msg, ret)
>= (int)sizeof(buffer))
{
buffer[sizeof(buffer) - 1] = 0;
}
wolfssl_log(LEAVE_LOG, NULL, 0, buffer);
}
}
Expand All @@ -538,8 +578,12 @@ void WOLFSSL_LEAVE2(const char *file, int line, const char* msg, int ret)
{
if (loggingEnabled) {
char buffer[WOLFSSL_MAX_ERROR_SZ];
XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
msg, ret);
if (XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
msg, ret)
>= (int)sizeof(buffer))
{
buffer[sizeof(buffer) - 1] = 0;
}
wolfssl_log(LEAVE_LOG, file, line, buffer);
}
}
Expand Down Expand Up @@ -1674,3 +1718,135 @@ void WOLFSSL_ERROR_MSG(const char* msg)
}

#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */

#ifdef WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES

#include <backtrace-supported.h>

#if BACKTRACE_SUPPORTED != 1
#error WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES is defined but BACKTRACE_SUPPORTED is 0.
#endif

#if !defined(WOLFSSL_MUTEX_INITIALIZER) && defined(WOLFSSL_NO_ATOMICS)
#error WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES requires WOLFSSL_MUTEX_INITIALIZER or wolfSSL_Atomic_Ints.
#endif

#include <backtrace.h>

static int backtrace_callback(void *data, uintptr_t pc, const char *filename,
int lineno, const char *function)
{
if (function == NULL)
return 0;
/* the first callback is for the call to wc_print_backtrace() -- skip it. */
if (*(int *)data == 0) {
*(int *)data = 1;
return 0;
}
#ifdef NO_STDIO_FILESYSTEM
printf(" #%d %p in %s %s:%d\n", (*(int *)data)++, (void *)pc,
function, filename, lineno);
#else
fprintf(stderr, " #%d %p in %s %s:%d\n", (*(int *)data)++, (void *)pc,
function, filename, lineno);
#endif
return 0;
}

static void backtrace_error(void *data, const char *msg, int errnum) {
(void)data;
#ifdef NO_STDIO_FILESYSTEM
printf("ERR TRACE: error %d while backtracing: %s", errnum, msg);
#else
fprintf(stderr, "ERR TRACE: error %d while backtracing: %s", errnum, msg);
#endif
}

static void backtrace_creation_error(void *data, const char *msg, int errnum) {
(void)data;
#ifdef NO_STDIO_FILESYSTEM
printf("ERR TRACE: internal error %d "
"while initializing backtrace facility: %s", errnum, msg);
printf("ERR TRACE: internal error "
"while initializing backtrace facility");
#else
fprintf(stderr, "ERR TRACE: internal error %d "
"while initializing backtrace facility: %s", errnum, msg);
#endif
}

static int backtrace_init(struct backtrace_state **backtrace_state) {
#ifdef WOLFSSL_MUTEX_INITIALIZER
static wolfSSL_Mutex backtrace_create_state_mutex =
WOLFSSL_MUTEX_INITIALIZER(backtrace_create_state_mutex);
if (wc_LockMutex(&backtrace_create_state_mutex) != 0)
return -1;
#elif defined(WOLFSSL_ATOMIC_OPS)
static wolfSSL_Atomic_Int init_count = 0;
if (wolfSSL_Atomic_Int_FetchAdd(&init_count, 1) != 1)
return -1;
#endif
if (*backtrace_state == NULL) {
/* passing a NULL filename to backtrace_create_state() tells
* libbacktrace to use a target-specific strategy to determine the
* executable. "libbacktrace supports ELF, PE/COFF, Mach-O, and XCOFF
* executables with DWARF debugging information. In other words, it
* supports GNU/Linux, *BSD, macOS, Windows, and AIX."
*/
*backtrace_state = backtrace_create_state(
NULL, 0, backtrace_creation_error, NULL);
}
#ifdef WOLFSSL_MUTEX_INITIALIZER
wc_UnLockMutex(&backtrace_create_state_mutex);
#endif
if (*backtrace_state == NULL)
return -1;
return 0;
}

void wc_backtrace_render(void) {
static wolfSSL_Mutex backtrace_mutex
WOLFSSL_MUTEX_INITIALIZER_CLAUSE(backtrace_mutex);
static struct backtrace_state *backtrace_state = NULL;
int depth = 0;

#ifndef WOLFSSL_MUTEX_INITIALIZER
static wolfSSL_Atomic_Int init_count = 0;
if (init_count != 1) {
int cur_init_count = wolfSSL_Atomic_Int_FetchSub(&init_count, 1);
if (cur_init_count != 0) {
(void)wolfSSL_Atomic_Int_FetchAdd(&init_count, 1);
return;
}
if (wc_InitMutex(&backtrace_mutex) != 0)
return;
/* set init_count to 1, race-free: (-1) - (0-2) = 1 */
(void)wolfSSL_Atomic_Int_FetchSub(&init_count, cur_init_count - 2);
}
#endif

/* backtrace_state can't be shared between threads even when
* BACKTRACE_SUPPORTS_THREADS == 1, so we serialize the render op. this
* helpfully mutexes the initialization too.
*/
if (wc_LockMutex(&backtrace_mutex) != 0)
return;

if (backtrace_state == NULL) {
if (backtrace_init(&backtrace_state) < 0) {
wc_UnLockMutex(&backtrace_mutex);
return;
}
}

/* note that the optimizer can produce misleading backtraces, even with
* -funwind-tables. in contrast, the macro-generated "ERR TRACE" message
* from WC_ERR_TRACE() always accurately identifies the error code point.
*/
backtrace_full(backtrace_state, 0, backtrace_callback, backtrace_error,
(void *)&depth);

wc_UnLockMutex(&backtrace_mutex);
}

#endif /* WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES */
8 changes: 6 additions & 2 deletions wolfcrypt/src/wc_kyber.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,9 @@ int wc_KyberKey_MakeKeyWithRandom(KyberKey* key, const unsigned char* rand,
}

/* Free dynamic memory allocated in function. */
XFREE(a, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (key != NULL) {
XFREE(a, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
}

return ret;
}
Expand Down Expand Up @@ -890,7 +892,9 @@ int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss,

#ifndef USE_INTEL_SPEEDUP
/* Dispose of dynamic memory allocated in function. */
XFREE(cmp, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (key != NULL) {
XFREE(cmp, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif

return ret;
Expand Down
Loading

0 comments on commit 2a08d30

Please sign in to comment.