5,260 research outputs found
Stateman: Using Metafunctions to Manage Large Terms Representing Machine States
When ACL2 is used to model the operational semantics of computing machines,
machine states are typically represented by terms recording the contents of the
state components. When models are realistic and are stepped through thousands
of machine cycles, these terms can grow quite large and the cost of simplifying
them on each step grows. In this paper we describe an ACL2 book that uses HIDE
and metafunctions to facilitate the management of large terms representing such
states. Because the metafunctions for each state component updater are solely
responsible for creating state expressions (i.e., "writing") and the
metafunctions for each state component accessor are solely responsible for
extracting values (i.e., "reading") from such state expressions, they can
maintain their own normal form, use HIDE to prevent other parts of ACL2 from
inspecting them, and use honsing to uniquely represent state expressions. The
last feature makes it possible to memoize the metafunctions, which can improve
proof performance in some machine models. This paper describes a
general-purpose ACL2 book modeling a byte-addressed memory supporting "mixed"
reads and writes. By "mixed" we mean that reads need not correspond (in address
or number of bytes) with writes. Verified metafunctions simplify such
"read-over-write" expressions while hiding the potentially large state
expression. A key utility is a function that determines an upper bound on the
value of a symbolic arithmetic expression, which plays a role in resolving
writes to addresses given by symbolic expressions. We also report on a
preliminary experiment with the book, which involves the production of states
containing several million function calls.Comment: In Proceedings ACL2 2015, arXiv:1509.0552
Proving Memory Safety of the ANI Windows Image Parser Using Compositional Exhaustive Testing
We report in this paper how we proved memory safety of a complex Windows image parser written in low-level C in only three months of work and using only three core tech-niques, namely (1) symbolic execution at the x86 binary level, (2) exhaustive program path enumeration and testing, and (3) user-guided program decomposition and summariza-tion. We also used a new tool, named MicroX, for executing code fragments in isolation using a custom virtual machine designed for testing purposes. As a result of this work, we are able to prove, for the first time, that a Windows image parser is memory safe, i.e., free of any buffer-overflow secu-rity vulnerabilities, modulo the soundness of our tools and several additional assumptions regarding bounding input-dependent loops, fixing a few buffer-overflow bugs, and ex-cluding some code parts that are not memory safe by design. In the process, we also discovered and fixed several limita-tions in our tools, and narrowed the gap between systematic testing and verification. 1
Proof-Producing Symbolic Execution for Binary Code Verification
We propose a proof-producing symbolic execution for verification of
machine-level programs. The analysis is based on a set of core inference rules
that are designed to give control over the tradeoff between preservation of
precision and the introduction of overapproximation to make the application to
real world code useful and tractable. We integrate our symbolic execution in a
binary analysis platform that features a low-level intermediate language
enabling the application of analyses to many different processor architectures.
The overall framework is implemented in the theorem prover HOL4 to be able to
obtain highly trustworthy verification results. We demonstrate our approach to
establish sound execution time bounds for a control loop program implemented
for an ARM Cortex-M0 processor
Guiding Dynamic Symbolic Execution Toward Unverified Program Executions
Most techniques to detect program errors, such as testing, code reviews, and static program analysis, do not fully verify all possible executions of a program. They leave executions unverified when they do not check certain properties, fail to verify properties, or check properties under certain unsound assumptions such as the absence of arithmetic overflow.
In this paper, we present a technique to complement partial verification results by automatic test case generation. In contrast to existing work, our technique supports the common case that the verification results are based on unsound assumptions. We annotate programs to reflect which executions have been verified, and under which assumptions. These annotations are then used to guide dynamic symbolic execution toward unverified program executions. Our main technical contribution is a code instrumentation that causes dynamic symbolic execution to abort tests that lead to verified executions, to prune parts of the search space, and to prioritize tests that cover more properties that are not fully verified. We have implemented our technique for the .NET static analyzer Clousot and the dynamic symbolic execution tool Pex. It produces smaller test suites (by up to 19.2%), covers more unverified executions (by up to 7.1%), and reduces testing time (by up to 52.4%) compared to combining Clousot and Pex without our technique
A formally verified compiler back-end
This article describes the development and formal verification (proof of
semantic preservation) of a compiler back-end from Cminor (a simple imperative
intermediate language) to PowerPC assembly code, using the Coq proof assistant
both for programming the compiler and for proving its correctness. Such a
verified compiler is useful in the context of formal methods applied to the
certification of critical software: the verification of the compiler guarantees
that the safety properties proved on the source code hold for the executable
compiled code as well
A Review of Formal Methods applied to Machine Learning
We review state-of-the-art formal methods applied to the emerging field of
the verification of machine learning systems. Formal methods can provide
rigorous correctness guarantees on hardware and software systems. Thanks to the
availability of mature tools, their use is well established in the industry,
and in particular to check safety-critical applications as they undergo a
stringent certification process. As machine learning is becoming more popular,
machine-learned components are now considered for inclusion in critical
systems. This raises the question of their safety and their verification. Yet,
established formal methods are limited to classic, i.e. non machine-learned
software. Applying formal methods to verify systems that include machine
learning has only been considered recently and poses novel challenges in
soundness, precision, and scalability.
We first recall established formal methods and their current use in an
exemplar safety-critical field, avionic software, with a focus on abstract
interpretation based techniques as they provide a high level of scalability.
This provides a golden standard and sets high expectations for machine learning
verification. We then provide a comprehensive and detailed review of the formal
methods developed so far for machine learning, highlighting their strengths and
limitations. The large majority of them verify trained neural networks and
employ either SMT, optimization, or abstract interpretation techniques. We also
discuss methods for support vector machines and decision tree ensembles, as
well as methods targeting training and data preparation, which are critical but
often neglected aspects of machine learning. Finally, we offer perspectives for
future research directions towards the formal verification of machine learning
systems
- âŠ