5 research outputs found
The SeaHorn Verification Framework
In this paper, we present SeaHorn, a software verification framework. The key distinguishing feature of SeaHorn is its modular design that separates the concerns of the syntax of the programming language, its operational semantics, and the verification semantics. SeaHorn encompasses several novelties: it (a) encodes verification conditions using an efficient yet precise inter-procedural technique, (b) provides flexibility in the verification semantics to allow different levels of precision, (c) leverages the state-of-the-art in software model checking and abstract interpretation for verification, and (d) uses Horn-clauses as an intermediate language to represent verification conditions which simplifies interfacing with multiple verification tools based on Horn-clauses. SeaHorn provides users with a powerful verification tool and researchers with an extensible and customizable framework for experimenting with new software verification techniques. The effectiveness and scalability of SeaHorn are demonstrated by an extensive experimental evaluation using benchmarks from SV-COMP 2015 and real avionics code
SMT-based Model Checking for Recursive Programs
We present an SMT-based symbolic model checking algorithm for safety
verification of recursive programs. The algorithm is modular and analyzes
procedures individually. Unlike other SMT-based approaches, it maintains both
"over-" and "under-approximations" of procedure summaries. Under-approximations
are used to analyze procedure calls without inlining. Over-approximations are
used to block infeasible counterexamples and detect convergence to a proof. We
show that for programs and properties over a decidable theory, the algorithm is
guaranteed to find a counterexample, if one exists. However, efficiency depends
on an oracle for quantifier elimination (QE). For Boolean Programs, the
algorithm is a polynomial decision procedure, matching the worst-case bounds of
the best BDD-based algorithms. For Linear Arithmetic (integers and rationals),
we give an efficient instantiation of the algorithm by applying QE "lazily". We
use existing interpolation techniques to over-approximate QE and introduce
"Model Based Projection" to under-approximate QE. Empirical evaluation on
SV-COMP benchmarks shows that our algorithm improves significantly on the
state-of-the-art.Comment: originally published as part of the proceedings of CAV 2014; fixed
typos, better wording at some place
Templates and Recurrences: Better Together
This paper is the confluence of two streams of ideas in the literature on
generating numerical invariants, namely: (1) template-based methods, and (2)
recurrence-based methods. A template-based method begins with a template that
contains unknown quantities, and finds invariants that match the template by
extracting and solving constraints on the unknowns. A disadvantage of
template-based methods is that they require fixing the set of terms that may
appear in an invariant in advance. This disadvantage is particularly prominent
for non-linear invariant generation, because the user must supply maximum
degrees on polynomials, bases for exponents, etc. On the other hand,
recurrence-based methods are able to find sophisticated non-linear mathematical
relations, including polynomials, exponentials, and logarithms, because such
relations arise as the solutions to recurrences. However, a disadvantage of
past recurrence-based invariant-generation methods is that they are primarily
loop-based analyses: they use recurrences to relate the pre-state and
post-state of a loop, so it is not obvious how to apply them to a recursive
procedure, especially if the procedure is non-linearly recursive (e.g., a
tree-traversal algorithm). In this paper, we combine these two approaches and
obtain a technique that uses templates in which the unknowns are functions
rather than numbers, and the constraints on the unknowns are recurrences. The
technique synthesizes invariants involving polynomials, exponentials, and
logarithms, even in the presence of arbitrary control-flow, including any
combination of loops, branches, and (possibly non-linear) recursion. For
instance, it is able to show that (i) the time taken by merge-sort is , and (ii) the time taken by Strassen's algorithm is
.Comment: 20 pages, 3 figure
Software Model Checking with Uninterpreted Functions
Software model checkers attempt to algorithmically synthesize an inductive
proof that a piece of software is safe.
Such proofs are composed of complex logical assertions about program variables
and control structures, and are computationally expensive to produce.
Our unifying motivation is to increase the efficiency of verifying software
control behavior despite its dependency on data.
Control properties include important topics such as mutual exclusion, safe
privilege elevation, and proper usage of networking and other APIs.
These concerns motivate our techniques and evaluations.
Our approach integrates an efficient abstraction procedure based on the logic
of equality with uninterpreted functions (EUF) into the core of a modern model
checker.
Our checker, called euforia, targets control properties by treating a
program's data operations and relations as uninterpreted functions and
predicates, respectively.
This reduces the cost of building inductive proofs, especially for verifying
control relationships in the presence of complex but irrelevant data
processing.
We show that our method is sound and terminates.
We provide a ground-up implementation and
evaluate the abstraction on a variety of software verification benchmarks.
We show how to extend this abstraction to memory-manipulating programs.
By judicious abstraction of array operations to EUF, we show that we can
directly reason about array reads and adaptively learn lemmas
about array writes leading to significant performance improvements over
existing approaches.
We show that our abstraction of array operations completely eliminates much of
the array theory reasoning otherwise required.
We report on experiments with and without abstraction and compare our checker
to the state of the art.
Programs with procedures pose unique difficulties and opportunities.
We show how to retrofit a model checker not supporting procedures so that it
supports modular analysis of programs with non-recursive procedures.
This technique applies to euforia as well as other logic-based algorithms.
We show that this technique enables logical assertions about procedure bodies
to be reused at different call sites.
We report on experiments on software benchmarks compared to the alternative of
inlining all procedures.PHDComputer Science & EngineeringUniversity of Michigan, Horace H. Rackham School of Graduate Studieshttp://deepblue.lib.umich.edu/bitstream/2027.42/168092/1/dlbueno_1.pd