1,435 research outputs found
Proving termination and memory safety for programs with Pointer Arithmetic
Proving termination automatically for programs with explicit pointer arithmetic is still an open problem. To close this gap, we introduce a novel abstract domain that can track allocated memory in detail. We use it to automatically construct a symbolic execution graph that represents all possible runs of the program and that can be used to prove memory safety. This graph is then transformed into an integer transition system, whose termination can be proved by standard techniques. We implemented this approach in the automated termination prover AProVE and demonstrate its capability of analyzing C programs with pointer arithmetic that existing tools cannot handle
Automatically proving termination and memory safety for programs with pointer arithmetic
While automated verification of imperative programs has been studied intensively, proving termination of programs with explicit pointer arithmetic fully automatically was still an open problem. To close this gap, we introduce a novel abstract domain that can track allocated memory in detail. We use it to automatically construct a symbolic execution graph that over-approximates all possible runs of a program and that can be used to prove memory safety. This graph is then transformed into an integer transition system, whose termination can be proved by standard techniques. We implemented this approach in the automated termination prover AProVE and demonstrate its capability of analyzing C programs with pointer arithmetic that existing tools cannot handle
The Meaning of Memory Safety
We give a rigorous characterization of what it means for a programming
language to be memory safe, capturing the intuition that memory safety supports
local reasoning about state. We formalize this principle in two ways. First, we
show how a small memory-safe language validates a noninterference property: a
program can neither affect nor be affected by unreachable parts of the state.
Second, we extend separation logic, a proof system for heap-manipulating
programs, with a memory-safe variant of its frame rule. The new rule is
stronger because it applies even when parts of the program are buggy or
malicious, but also weaker because it demands a stricter form of separation
between parts of the program state. We also consider a number of pragmatically
motivated variations on memory safety and the reasoning principles they
support. As an application of our characterization, we evaluate the security of
a previously proposed dynamic monitor for memory safety of heap-allocated data.Comment: POST'18 final versio
Automated Termination Proofs for C Programs with Lists (Short WST Version)
There are many techniques and tools for termination of C programs, but up to
now they were not very powerful for termination proofs of programs whose
termination depends on recursive data structures like lists. We present the
first approach that extends powerful techniques for termination analysis of C
programs (with memory allocation and explicit pointer arithmetic) to lists.Comment: Presented at WST 2023, short version of arXiv:2305.1215
Propositional Reasoning about Safety and Termination of Heap-Manipulating Programs
This paper shows that it is possible to reason about the safety and
termination of programs handling potentially cyclic, singly-linked lists using
propositional reasoning even when the safety invariants and termination
arguments depend on constraints over the lengths of lists. For this purpose, we
propose the theory SLH of singly-linked lists with length, which is able to
capture non-trivial interactions between shape and arithmetic. When using the
theory of bit-vector arithmetic as a background, SLH is efficiently decidable
via a reduction to SAT. We show the utility of SLH for software verification by
using it to express safety invariants and termination arguments for programs
manipulating potentially cyclic, singly-linked lists with unrestricted,
unspecified sharing. We also provide an implementation of the decision
procedure and use it to check safety and termination proofs for several
heap-manipulating programs
2LS: memory safety and non-termination (competition contribution)
2LS is a C program analyser built upon the CPROVER infrastructure. 2LS is bit-precise and it can verify and refute program assertions and termination. 2LS implements template-based synthesis techniques, e.g. to find invariants and ranking functions, and incremental loop unwinding techniques to find counterexamples and -induction proofs. New features in this year's version are improved handling of
heap-allocated data structures using a template domain for shape analysis and two approaches to prove program non-termination
Automated verification of shape, size and bag properties.
In recent years, separation logic has emerged as a contender for formal reasoning of heap-manipulating imperative programs. Recent works have focused on specialised provers that are mostly based on fixed sets of predicates. To improve expressivity, we have proposed a prover that can automatically handle user-defined predicates. These shape predicates allow programmers to describe a wide range of data structures with their associated size properties. In the current work, we shall enhance this prover by providing support for a new type of constraints, namely bag (multi-set) constraints. With this extension, we can capture the reachable nodes (or values) inside a heap predicate as a bag constraint. Consequently, we are able to prove properties about the actual values stored inside a data structure
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
CapablePtrs: Securely Compiling Partial Programs using the Pointers-as-Capabilities Principle
Capability machines such as CHERI provide memory capabilities that can be
used by compilers to provide security benefits for compiled code (e.g., memory
safety). The C to CHERI compiler, for example, achieves memory safety by
following a principle called "pointers as capabilities" (PAC). Informally, PAC
says that a compiler should represent a source language pointer as a machine
code capability. But the security properties of PAC compilers are not yet well
understood. We show that memory safety is only one aspect, and that PAC
compilers can provide significant additional security guarantees for partial
programs: the compiler can provide guarantees for a compilation unit, even if
that compilation unit is later linked to attacker-controlled machine code. This
paper is the first to study the security of PAC compilers for partial programs
formally. We prove for a model of such a compiler that it is fully abstract.
The proof uses a novel proof technique (dubbed TrICL, read trickle), which is
of broad interest because it reuses and extends the compiler correctness
relation in a natural way, as we demonstrate. We implement our compiler on top
of the CHERI platform and show that it can compile legacy C code with minimal
code changes. We provide performance benchmarks that show how performance
overhead is proportional to the number of cross-compilation-unit function
calls
- …