GrammaTech CodeSonar Analysis of a bug in wolfSSL

March 24, 2020 Mark Hermeling

wofssl-gt

WolfSSL is a lightweight, portable, and embedded SSL/TLS library. Written in C it’s 20 times smaller than OpenSSL. The code is open source but wolfSSL is also available with commercial support. We decided to take a look at the code with CodeSonar to see if there are any bugs or vulnerabilities to be found. In short, we found an uninitialized variable bug that gets somewhat exacerbated by compiler options that disable diagnostics.

Here is part of the report from CodeSonar.

GrammaTech Code Sonar Analysis of a bug in wolfssl Pic 1 V0.2

wc_AesEncrypt is normally expected to write data to outBlock.In this calling context, this is then passed into xorbuf as the parameter EKY0 on line 6129.

What CodeSonar is found is that there is a possible abnormal situation where wc_AesEncrypt returns early without having written to that buffer. Reading uninitialized memory is undefined behavior, so this is clearly a potentially serious bug. However what CodeSonar also makes clear is that a helpful diagnostic is also suppressed due to the way the code is compiled.

Line 1410 above makes it clear that the intention was to send a warning message to the user but in this build, that won’t happen because WOLFSSL_MSG() expands to a macro that does nothing. That line is useful in a debugging context, but that’s not helpful if this error were to trigger in the field.

Here’s the definition of WOLFSSL_MSG in wolfssl/wolfcrypt/logging.c:

#ifndef WOLFSSL_DEBUG_ERRORS_ONLY
void WOLFSSL_MSG(const char* msg)
{
  if (loggingEnabled)
    wolfssl_log(INFO_LOG , msg);
}

In this particular case, CodeSonar’s deep analysis has followed possible paths in the application, including error conditions, like in this example. 

#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_DEBUG_ERRORS_ONLY)
  …
     WOLFSSL_API void WOLFSSL_MSG(const char* msg);
  …
#else
  …
  #define WOLFSSL_MSG(m)
  …
#endif
 

Note the macro in the else part of the #ifdef that causes WOLFSSL_MSG to expand to nothing.

This illustrates two notable things about CodeSonar’s analysis. First, because it does a very precise parse of the code, it knows exactly how the preprocessor macros were expanded. Because complicated preprocessor directives can be very difficult to understand, this knowledge helps users see through the confusion easily.

Second, note that the path that leads to the read of the uninitialized memory is an error path. Such paths are not typically executed very often, and can be quite difficult to test, especially in combination, so there is a much higher probability that bugs are found along those paths. Consequently, these are the paths that attackers often try to exploit because it can give them a foothold that ultimately allows them to implement an exploit. This is a key strength of path-sensitive static analysis: in principle it is capable of exploring all paths of execution, so it is good at finding bugs in the corner cases.

 

Interested in learning more? Read our guide "Advanced Static Analysis for C/C++"

Previous Article
How to Configure GrammaTech CodeSonar to Support Your Work from Home Environment
How to Configure GrammaTech CodeSonar to Support Your Work from Home Environment

These are unusual times for businesses around the world and the people that work in them. All of...

Next Article
The Role of Static Analysis in the EU Medical Devices Regulation (MDR)
The Role of Static Analysis in the EU Medical Devices Regulation (MDR)

The move to digitization and automation is happening in the medical industry as it is in others ...