Retrofitting automated verification to systems code by scaling symbolic evaluation
Loading...
Date
Authors
Journal Title
Journal ISSN
Volume Title
Publisher
Abstract
Formal verification is a technique for eliminating classes of bugs insystems software by formally proving that a system's implementation
meets its intended specification. While effective at systematically
preventing hard-to-catch bugs, formal verification demands a
significant effort from developers in the form of manual proofs.
Automated verification techniques reduce the burden of verification by
leveraging automated reasoning to avoid the need for manual proofs.
But as a result, they sacrifice generality and require developers to
build bespoke verification tools and to carefully design systems with
automated verification in mind. This dissertation explores how to make it easier to build andreuse automated verifiers, and how to retrofit systems to automated
verification. To do so, we built Serval, a framework for writing
automated verifiers for systems code. To use Serval, developers write
an interpreter for a language; Serval then leverages the Rosette
programming language to lift the interpreter into a verifier via
symbolic evaluation. Serval also comes with a set of techniques and
optimizations to help overcome verification bottlenecks. We use Serval to develop automated verifiers for RISC-V, x86, Arm,LLVM IR, and BPF. We apply these verifiers to retrofit automated
verification to two existing security monitors previously formally
verified using other techniques: CertiKOS, an OS kernel with strict
process isolation, and Komodo, a monitor that implements secure
enclaves. We port these two systems to RISC-V, modifying their
interfaces for automated verification and to improve security.
We write specifications amenable to automation, and compare our
efforts with that of the original systems. To demonstrate applicability to systems beyond security monitors, weuse Serval to build Jitterbug, a framework for writing and verifying
just-in-time (JIT) compilers for the Berkeley Packet Filter (BPF)
language in the Linux kernel. We develop a specification of compiler
correctness suitable for these JITs. Using this approach, we found
and fixed more than 30 new bugs in the JITs in the Linux kernel and
developed a new, verified BPF JIT for 32-bit RISC-V.
Description
Thesis (Ph.D.)--University of Washington, 2025
