Software Assurance            Software Hardening            Autonomic Computing

Domain Specific and Custom Error Checking in Advanced Static Analysis Tools


INTRODUCTION:

Static analysis tools ship with a default set of error checkers that cover the most common and important types of errors. However, projects often benefit from specific checks that apply to their domain such as very specific coding standards, correct usage of API functions, and security guidelines. Advanced static analysis tools have the capability to create custom, domain specific, checkers via various means including programming to an exposed API. This post provides a brief summary of how custom checkers work within the architecture of an advanced static analysis tool, how they are implemented and possible applications.

GRMT348_Grammatech_Box_760x400_Checks.jpg

Related:


How Advanced Static Analysis Tools Work 

Static analysis tools parse code similarly to a compiler into an intermediate representation (IR) which contains the program’s abstract syntax tree (AST) and a control flow graph (CFG). A block diagram of this architecture is shown in Figure 1. The IR is traversed by the static analyzer looking for patterns or properties that indicate errors. Simple tools usually only look at the AST to detect syntactical errors whereas more advanced tools use symbolic execution of the CFG to detect complex errors that can span multiple files or functions/procedures.

Static_Analysis_Architecture.png

Figure 1: The architecture of an advanced static analysis tool

Domain specific error detection can be applied by modifying the behavior of an existing checker via configuration files or code annotations, or by extending the behaviour by adding custom checkers written in a programming language against the API that the tool provides.

Customizing the Analysis

Configuration

An easy and effective way to customize static analysis results is through configuration (often a text file) that specifies what checkers are on or off and options for certain errors types. For example, a checker that detects forbidden function calls can be modified to include a customized list. Projects can specify a custom list of errors plus restricted functions and API calls.

Code Annotations

Some static analysis tools allow for inline code to perform checks. GrammaTech CodeSonar handles this with csonar_trigger()function (hidden from the compiler with directives.) For example, the function foo() below can be annotated as follows:

void foo(int x) {
#ifdef __CSURF__
csonar_trigger(x, “==”, -1, “Dangerous call to foo()”);
#endif __CSURF__
  ...
}

An alternative to annotating in place, CodeSonar provides function substitution via the csonar_replace_x() function, where “x” is a valid function name in the application. Using foo() as the example again: 

void csonar_replace_foo( int x ) {
csonar_trigger(x, “==”, -1, “Dangerous call to foo()”);
foo();
}

When the analysis detects the csonar_replace_foo definition, it treats all calls to foo() as calls to csonar_replace_foo() instead (not including the call to foo() within the definition itself.) 

Custom Checkers via API

Exposing an API to the internal representation of the source provides another means of creating custom checkers. In CodeSonar, custom checkers can be implemented as user-supplied callbacks that are called with each IR element during the analysis. The user specifies what type of object in the IR the callback function is to be called on. For checking variable names, for example, a symbol callback could be supplied to be called on each variable and function symbol in the program. The checker can then perform analysis based on details of the symbol. CodeSonar also provides access to control flow graph which allows for sophisticated checkers that trace execution and data flow.

These type of custom checkers can, for ease-of-use, be written in Python. If performance is important, then they can be ported to C++.

Applications

Customizing static analysis to suit the development team needs is common practice. Even if it’s turning on or off checkers that aren’t critical. Here are some examples of applications of customized static analysis:

  • Company or Industry Coding Standard: Project teams often have coding standards but struggle to enforce them. Static analysis is a perfect tool for flagging coding standard violations. Customizing existing guidelines or creating a new set is fairly straightforward with tool configuration or adding checkers via an API.
  • Security Guidelines: A secure coding standard could be based on Cert C plus a customized list of security rules specific to a project. Although this overlaps with the coding standards above, the errors produced are handled as “security violations” rather than coding or stylistic infractions. An example could be that data from a specific object should never end up in networking related functions without being encrypted first.
  • Logic Checkers: Programs often have invariants that can be checked to make sure that they are not violated as the code base grows and a team churns. Another example is validation of specific properties on the output of a program. The CodeSonar manual has an example of how to check whether a program generates output that has it’s brackets and parentheses perfectly balanced.
  • State-based Checkers: In CodeSonar code annotations are perfect for evaluating temporal behavior. Suppose there is a rule that says that bar() should never be called while foo() is executing. A check might be implemented as follows:
    static int foo_is_executing = 0;

    void csonar_replace_foo(int x) {
    foo_is_executing = 1;
    foo();
    foo_is_executing = 0;
    }
    void csonar_replace_bar(void) {
    csonar_trigger(foo_is_executing, “==”, 1, “Call to bar from foo”);
    bar();
    }

CONCLUSION:

Customization of error checking in advanced static analysis tools is critical for their integration into a development teams’ processes and coding practices. In GrammaTech CodeSonar, further customizations are available via code annotations and an API that provide the necessary “hooks” into the static analysis engine. Customization allows teams to select the appropriate set of checks for their project increasing the value that they derive from static analysis.


 Like what you read? Download our white paper "Detecting Domain-Specific Coding Errors with Static Analysis" to learn more.

Read the Guide