CPROVER Manual TOC

## Introduction

### Motivation

Numerous tools to hunt down functional design flaws in silicon have been available for many years, mainly due to the enormous cost of hardware bugs. The use of such tools is wide-spread. In contrast, the market for tools that address the need for quality software is still in its infancy.

Research in software quality has an enormous breadth. We focus the presentation using two criteria:

1. We believe that any form of quality requires a specific guarantee, in theory and practice.
2. The sheer size of software designs requires techniques that are highly automated.

In practice, quality guarantees usually do not refer to "total correctness" of a design, as ensuring the absence of all bugs is too expensive for most applications. In contrast, a guarantee of the absence of specific flaws is achievable, and is a good metric of quality.

We document two programs that try to achieve formal guarantees of the absence of specific problems: CBMC and SATABS. The algorithms implemented by CBMC and SATABS are complementary, and often, one tool is able to solve a problem that the other cannot solve.

Both CBMC and SATABS are verification tools for ANSI-C/C++ programs. They verify array bounds (buffer overflows), pointer safety, exceptions and user-specified assertions. Both tools model integer arithmetic accurately, and are able to reason about machine-level artifacts such as integer overflow. CBMC and SATABS are therefore able to detect a class of bugs that has so far gone unnoticed by many other verification tools. This manual also covers some variants of CBMC, which includes HW-CBMC for hardware/software co-verification.

### Bounded Model Checking with CBMC

CBMC implements a technique called Bounded Model Checking (BMC). In BMC, the transition relation for a complex state machine and its specification are jointly unwound to obtain a Boolean formula, which is then checked for satisfiability by using an efficient SAT procedure. If the formula is satisfiable, a counterexample is extracted from the output of the SAT procedure. If the formula is not satisfiable, the program can be unwound more to determine if a longer counterexample exists.

In many engineering domains, real-time guarantees are a strict requirement. An example is software embedded in automotive controllers. As a consequence, the loop constructs in these types of programs often have a strict bound on the number of iterations. CBMC is able to formally verify such bounds by means of unwinding assertions. Once this bound is established, CBMC is able to prove the absence of errors.

A more detailed description of how to apply CBMC verify programs is here.

### Automatic Program Verification with SATABS

In many cases, lightweight properties such as array bounds do not rely on the entire program. A large fraction of the program is irrelevant to the property. SATABS exploits this observation and computes an abstraction of the program in order to handle large amounts of code.

In order to use SATABS it is not necessary to understand the abstraction refinement process. For the interested reader, a high-level introduction to abstraction refinement is provided here. We also provide tutorials on how to use SATABS.

Just as CBMC, SATABS attempts to build counterexamples that refute the property. If such a counterexample is found, it is presented to the engineer to facilitate localization and repair of the program.

Example: Buffer Overflows

In order to give a brief overview of the capabilities of CBMC and SATABS we start with a small example. The issue of buffer overflows has obtained wide public attention. A buffer is a contiguously-allocated chunk of memory, represented by an array or a pointer in C. Programs written in C do not provide automatic bounds checking on the buffer, which means a program can – accidentally or maliciously – write past a buffer. The following example is a perfectly valid C program (in the sense that a compiler compiles it without any errors):

`int main() {
int buffer[10];
buffer[20] = 10;
}`

However, the write access to an address outside the allocated memory region can lead to unexpected behavior. In particular, such bugs can be exploited to overwrite the return address of a function, thus enabling the execution of arbitrary user-induced code. CBMC and SATABS are able to detect this problem and reports that the "upper bound property" of the buffer is violated. CBMC and SATABS are capable of checking these lower and upper bounds, even for arrays with dynamic size. A detailed discussion of the properties that CBMC and SATABS can check automatically is here.

### Hardware/Software Co-Verification

Software programs often interact with hardware in a non-trivial manner, and many properties of the overall design only arise from the interplay of both components. CBMC and SATABS therefore support Co-Verification, i.e., are able to reason about a C/C++ program together with a circuit description given in Verilog.

These co-verification capabilities can also be applied to perform refinement proofs. Software programs are often used as high-level descriptions of circuitry. While both describe the same functionality, the hardware implementation usually contains more detail. It is highly desirable to establish some form for equivalence between the two descriptions. Hardware/Software co-verification and equivalence checking with CBMC and SATABS are described here.

Further Reading

- Bounded Model Checking with CBMC
- Predicate Abstraction with SATABS
- Hardware/Software Co-Verification