Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The static analysis of C/C++ is a bit different from the analysis of other programming languages because the preprocessor complicates the analysis process a little bit. Resolving header files and macros, used in the preprocessing phase, is essential for a complete and correct C/C++ static code analysis. Let’s break down step by step how to analyze a C application with Kiuwan Code Security.

...

Analyzing in the cloud

We use the linux ftp Linux FTP server (linux-ftpd-0.17) as our sample application. The source code was downloaded from https://launchpad.net/ubuntu/utopic/+source/linux-ftpd.

...

The file .unresolved.headers.log has the list of header files that were not found during the analysis. These files are not mandatory for a successful analysis, but they can help you to know where you have declared some macros that are subsequently used.

Our first parsing error.

Cannot parse C:\_dev\c\linux-ftpd-0.17\ftpd\extern.h, due to: Parse error at line 38, column 1. Encountered: void
line[38]: void blkfree __P((char **));

This error is due to the macro __P, which was not found during the analysis. This symbol is known as a parameter wrapper. It is a kind of macro, often used in sources that are meant to be compatible with pre-ANSI compilers to protect parameter declarations in function prototypes.

This macro, in our system, is located in /usr/include/x86_64-linux-gnu/sys/cdefs.h file, and is defined as:

#define __P(args) args

The sys/cdefs.h file file was one of the listed in the log file c.unresolved.headers.log.

...

Once one error is fixed, we need to analyze analyze it again, since some errors are hidden or caused by another one. In the new log file, after the second analysis, we get:

Cannot parse C:\_dev\c\linux-ftpd-0.17\ftpd\ftpd.c, due to: Parse error at line 1644, column 1. Encountered: reply
line[1644]: reply(int n, char *fmt, va_dcl va_alist)

Seeing the code, around line 1644, we find:

#ifdef __STDC__
reply(int n, const char *fmt, …)
#else
reply(int n, char *fmt, va_dcl va_alist)
#endif

Our analyzer does not support the LEGACY mode to handle variable argument lists used in va_dcl va_alist.

...