@@ -471,26 +471,48 @@ void WOLFSSL_BUFFER(const byte* buffer, word32 length)
471471
472472 while (buflen > 0 ) {
473473 int bufidx = 0 ;
474- XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "\t" );
474+ if (XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "\t" )
475+ >= (int )sizeof (line ) - bufidx )
476+ {
477+ goto errout ;
478+ }
475479 bufidx ++ ;
476480
477481 for (i = 0 ; i < LINE_LEN ; i ++ ) {
478482 if (i < buflen ) {
479- XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "%02x " , buffer [i ]);
483+ if (XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "%02x " ,
484+ buffer [i ]) >= (int )sizeof (line ) - bufidx )
485+ {
486+ goto errout ;
487+ }
480488 }
481489 else {
482- XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , " " );
490+ if (XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , " " )
491+ >= (int )sizeof (line ) - bufidx )
492+ {
493+ goto errout ;
494+ }
483495 }
484496 bufidx += 3 ;
485497 }
486498
487- XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "| " );
499+ if (XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx , "| " )
500+ >= (int )sizeof (line ) - bufidx )
501+ {
502+ goto errout ;
503+ }
488504 bufidx ++ ;
489505
490506 for (i = 0 ; i < LINE_LEN ; i ++ ) {
491507 if (i < buflen ) {
492- XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx ,
493- "%c" , 31 < buffer [i ] && buffer [i ] < 127 ? buffer [i ] : '.' );
508+ if (XSNPRINTF (& line [bufidx ], sizeof (line )- bufidx ,
509+ "%c" , 31 < buffer [i ] && buffer [i ] < 127
510+ ? buffer [i ]
511+ : '.' )
512+ >= (int )sizeof (line ) - bufidx )
513+ {
514+ goto errout ;
515+ }
494516 bufidx ++ ;
495517 }
496518 }
@@ -499,14 +521,24 @@ void WOLFSSL_BUFFER(const byte* buffer, word32 length)
499521 buffer += LINE_LEN ;
500522 buflen -= LINE_LEN ;
501523 }
524+
525+ return ;
526+
527+ errout :
528+
529+ wolfssl_log (INFO_LOG , NULL , 0 , "\t[Buffer error while rendering]" );
502530}
503531
504532#undef WOLFSSL_ENTER /* undo WOLFSSL_DEBUG_CODEPOINTS wrapper */
505533void WOLFSSL_ENTER (const char * msg )
506534{
507535 if (loggingEnabled ) {
508536 char buffer [WOLFSSL_MAX_ERROR_SZ ];
509- XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Entering %s" , msg );
537+ if (XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Entering %s" , msg )
538+ >= (int )sizeof (buffer ))
539+ {
540+ buffer [sizeof (buffer ) - 1 ] = 0 ;
541+ }
510542 wolfssl_log (ENTER_LOG , NULL , 0 , buffer );
511543 }
512544}
@@ -516,7 +548,11 @@ void WOLFSSL_ENTER2(const char *file, int line, const char* msg)
516548{
517549 if (loggingEnabled ) {
518550 char buffer [WOLFSSL_MAX_ERROR_SZ ];
519- XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Entering %s" , msg );
551+ if (XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Entering %s" , msg )
552+ >= (int )sizeof (buffer ))
553+ {
554+ buffer [sizeof (buffer ) - 1 ] = 0 ;
555+ }
520556 wolfssl_log (ENTER_LOG , file , line , buffer );
521557 }
522558}
@@ -527,8 +563,12 @@ void WOLFSSL_LEAVE(const char* msg, int ret)
527563{
528564 if (loggingEnabled ) {
529565 char buffer [WOLFSSL_MAX_ERROR_SZ ];
530- XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Leaving %s, return %d" ,
531- msg , ret );
566+ if (XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Leaving %s, return %d" ,
567+ msg , ret )
568+ >= (int )sizeof (buffer ))
569+ {
570+ buffer [sizeof (buffer ) - 1 ] = 0 ;
571+ }
532572 wolfssl_log (LEAVE_LOG , NULL , 0 , buffer );
533573 }
534574}
@@ -538,8 +578,12 @@ void WOLFSSL_LEAVE2(const char *file, int line, const char* msg, int ret)
538578{
539579 if (loggingEnabled ) {
540580 char buffer [WOLFSSL_MAX_ERROR_SZ ];
541- XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Leaving %s, return %d" ,
542- msg , ret );
581+ if (XSNPRINTF (buffer , sizeof (buffer ), "wolfSSL Leaving %s, return %d" ,
582+ msg , ret )
583+ >= (int )sizeof (buffer ))
584+ {
585+ buffer [sizeof (buffer ) - 1 ] = 0 ;
586+ }
543587 wolfssl_log (LEAVE_LOG , file , line , buffer );
544588 }
545589}
@@ -1674,3 +1718,135 @@ void WOLFSSL_ERROR_MSG(const char* msg)
16741718}
16751719
16761720#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
1721+
1722+ #ifdef WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES
1723+
1724+ #include <backtrace-supported.h>
1725+
1726+ #if BACKTRACE_SUPPORTED != 1
1727+ #error WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES is defined but BACKTRACE_SUPPORTED is 0.
1728+ #endif
1729+
1730+ #if !defined(WOLFSSL_MUTEX_INITIALIZER ) && defined(WOLFSSL_NO_ATOMICS )
1731+ #error WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES requires WOLFSSL_MUTEX_INITIALIZER or wolfSSL_Atomic_Ints.
1732+ #endif
1733+
1734+ #include <backtrace.h>
1735+
1736+ static int backtrace_callback (void * data , uintptr_t pc , const char * filename ,
1737+ int lineno , const char * function )
1738+ {
1739+ if (function == NULL )
1740+ return 0 ;
1741+ /* the first callback is for the call to wc_print_backtrace() -- skip it. */
1742+ if (* (int * )data == 0 ) {
1743+ * (int * )data = 1 ;
1744+ return 0 ;
1745+ }
1746+ #ifdef NO_STDIO_FILESYSTEM
1747+ printf (" #%d %p in %s %s:%d\n" , (* (int * )data )++ , (void * )pc ,
1748+ function , filename , lineno );
1749+ #else
1750+ fprintf (stderr , " #%d %p in %s %s:%d\n" , (* (int * )data )++ , (void * )pc ,
1751+ function , filename , lineno );
1752+ #endif
1753+ return 0 ;
1754+ }
1755+
1756+ static void backtrace_error (void * data , const char * msg , int errnum ) {
1757+ (void )data ;
1758+ #ifdef NO_STDIO_FILESYSTEM
1759+ printf ("ERR TRACE: error %d while backtracing: %s" , errnum , msg );
1760+ #else
1761+ fprintf (stderr , "ERR TRACE: error %d while backtracing: %s" , errnum , msg );
1762+ #endif
1763+ }
1764+
1765+ static void backtrace_creation_error (void * data , const char * msg , int errnum ) {
1766+ (void )data ;
1767+ #ifdef NO_STDIO_FILESYSTEM
1768+ printf ("ERR TRACE: internal error %d "
1769+ "while initializing backtrace facility: %s" , errnum , msg );
1770+ printf ("ERR TRACE: internal error "
1771+ "while initializing backtrace facility" );
1772+ #else
1773+ fprintf (stderr , "ERR TRACE: internal error %d "
1774+ "while initializing backtrace facility: %s" , errnum , msg );
1775+ #endif
1776+ }
1777+
1778+ static int backtrace_init (struct backtrace_state * * backtrace_state ) {
1779+ #ifdef WOLFSSL_MUTEX_INITIALIZER
1780+ static wolfSSL_Mutex backtrace_create_state_mutex =
1781+ WOLFSSL_MUTEX_INITIALIZER (backtrace_create_state_mutex );
1782+ if (wc_LockMutex (& backtrace_create_state_mutex ) != 0 )
1783+ return -1 ;
1784+ #elif defined(WOLFSSL_ATOMIC_OPS )
1785+ static wolfSSL_Atomic_Int init_count = 0 ;
1786+ if (wolfSSL_Atomic_Int_FetchAdd (& init_count , 1 ) != 1 )
1787+ return -1 ;
1788+ #endif
1789+ if (* backtrace_state == NULL ) {
1790+ /* passing a NULL filename to backtrace_create_state() tells
1791+ * libbacktrace to use a target-specific strategy to determine the
1792+ * executable. "libbacktrace supports ELF, PE/COFF, Mach-O, and XCOFF
1793+ * executables with DWARF debugging information. In other words, it
1794+ * supports GNU/Linux, *BSD, macOS, Windows, and AIX."
1795+ */
1796+ * backtrace_state = backtrace_create_state (
1797+ NULL , 0 , backtrace_creation_error , NULL );
1798+ }
1799+ #ifdef WOLFSSL_MUTEX_INITIALIZER
1800+ wc_UnLockMutex (& backtrace_create_state_mutex );
1801+ #endif
1802+ if (* backtrace_state == NULL )
1803+ return -1 ;
1804+ return 0 ;
1805+ }
1806+
1807+ void wc_backtrace_render (void ) {
1808+ static wolfSSL_Mutex backtrace_mutex
1809+ WOLFSSL_MUTEX_INITIALIZER_CLAUSE (backtrace_mutex );
1810+ static struct backtrace_state * backtrace_state = NULL ;
1811+ int depth = 0 ;
1812+
1813+ #ifndef WOLFSSL_MUTEX_INITIALIZER
1814+ static wolfSSL_Atomic_Int init_count = 0 ;
1815+ if (init_count != 1 ) {
1816+ int cur_init_count = wolfSSL_Atomic_Int_FetchSub (& init_count , 1 );
1817+ if (cur_init_count != 0 ) {
1818+ (void )wolfSSL_Atomic_Int_FetchAdd (& init_count , 1 );
1819+ return ;
1820+ }
1821+ if (wc_InitMutex (& backtrace_mutex ) != 0 )
1822+ return ;
1823+ /* set init_count to 1, race-free: (-1) - (0-2) = 1 */
1824+ (void )wolfSSL_Atomic_Int_FetchSub (& init_count , cur_init_count - 2 );
1825+ }
1826+ #endif
1827+
1828+ /* backtrace_state can't be shared between threads even when
1829+ * BACKTRACE_SUPPORTS_THREADS == 1, so we serialize the render op. this
1830+ * helpfully mutexes the initialization too.
1831+ */
1832+ if (wc_LockMutex (& backtrace_mutex ) != 0 )
1833+ return ;
1834+
1835+ if (backtrace_state == NULL ) {
1836+ if (backtrace_init (& backtrace_state ) < 0 ) {
1837+ wc_UnLockMutex (& backtrace_mutex );
1838+ return ;
1839+ }
1840+ }
1841+
1842+ /* note that the optimizer can produce misleading backtraces, even with
1843+ * -funwind-tables. in contrast, the macro-generated "ERR TRACE" message
1844+ * from WC_ERR_TRACE() always accurately identifies the error code point.
1845+ */
1846+ backtrace_full (backtrace_state , 0 , backtrace_callback , backtrace_error ,
1847+ (void * )& depth );
1848+
1849+ wc_UnLockMutex (& backtrace_mutex );
1850+ }
1851+
1852+ #endif /* WOLFSSL_DEBUG_BACKTRACE_ERROR_CODES */
0 commit comments