Advanced static analyzers consider data that is passed between procedures/functions. It helps detect more errors and security flaws. It's important when we search for bugs such as buffer overruns, leaked credentials (taint analysis), null dereferences, etc. because resource is often created, used, and released in different functions.
Static analyzers use interprocedural context-sensitive code analysis to detect errors that occur when several procedures interact. If these functions are located in different program modules, the intermodular analysis is to be used.
Take a look at an example of an error detected by the PVS-Studio intermodular analysis in the Midnight Commander project written in C.
Let's start with the widget_destroy function in the widget-common.c file:
void widget_destroy (Widget * w)
{
send_message (w, NULL, MSG_DESTROY, 0, NULL);
g_free (w);
}
It's essential that the function releases the memory buffer. Its address is taken from the w argument.
Now let's look at the code in the editcmd.c file:
gboolean edit_close_cmd (WEdit * edit)
{
Widget *w = WIDGET (edit);
....
widget_destroy (w); // <= The memory was released here
if (....) .... else
{
edit = find_editor (DIALOG (g));
if (edit != NULL)
widget_select (w); // <= Take a look inside
}
}
Note that the address of the Widget structure is first passed to the widget_destroy function, where the memory buffer is released. Then, the pointer is passed to the widget_select function that we can see below:
void widget_select (Widget * w)
{
WGroup *g;
if (!widget_get_options (w, WOP_SELECTABLE))
return;
....
}
It just passes the pointer to the widget_get_options function:
static inline gboolean
widget_get_options (const Widget * w, widget_options_t options)
{
return ((w->options & options) == options);
}
Here, we have reached the point where undefined behavior occurs because of data being used in the already released memory buffer. The PVS-Studio analyzer issues a warning:
V774 The 'w' pointer was used after the memory was released.
This is a rather simple case where we use only two files: widget-common.c and editcmd.c. Errors can also be detected in longer call chains spread across three or more files. However, in reality, static analyzers are limited in the call analysis depth. The limits are both theoretical (halting problem) and practical (high-computational complexity). So, it's a good idea to combine static and dynamic code analysis.
Additional links
0