Deploy VeriFast to Europe โ Bart Jacobs ๐ง๐ช + KU Leuven (2008), the Separation Logic Verifier for C and Java with Symbolic Execution and Fractional Permissions, on EU Infrastructure in 2026
Verifying C and Java programs requires reasoning about heap aliasing. Two pointers may refer to the same memory location; a function may mutate data structures through a pointer that the caller still holds. Classic Hoare logic has no clean way to express "this function only modifies the subgraph it owns." Separation logic, introduced by John Reynolds and Peter O'Hearn in the early 2000s, solved this with a new connective: the separating conjunction P * Q asserts that P and Q hold for disjoint portions of the heap. VeriFast brings separation logic to practice.
VeriFast is a modular deductive verifier for C and Java programs, developed at KU Leuven ๐ง๐ช (Katholieke Universiteit Leuven) by Bart Jacobs and Frank Piessens, first presented at iFM 2008 (Integrated Formal Methods, Toulouse ๐ซ๐ท). VeriFast combines separation logic specifications with a symbolic execution engine: the verifier executes a symbolic program state through the code, consuming and producing heap predicates at each step, and emits proof obligations that an SMT solver (Z3) discharges automatically.
KU Leuven is one of Europe's oldest and most distinguished research universities โ founded in 1425 in Leuven, Belgium, it has been a centre of scientific excellence for six centuries. The VeriFast group works alongside Frank Piessens' security research team, which produced landmark work on Spectre and Meltdown CPU vulnerabilities. Both projects share the same institutional commitment: building trustworthy systems software on EU soil.
Specification Language โ Contract Comments
VeriFast specifications live in C and Java comments, invisible to the standard compiler but parsed by the VeriFast front-end. For C:
//@ requires integer(p, ?v) &*& integer(q, ?w);
//@ ensures integer(p, w) &*& integer(q, v);
void swap(int *p, int *q)
{
int tmp = *p;
*p = *q;
*q = tmp;
}
The ?v syntax introduces a pattern variable: "there exists some value v such that *p == v at entry." The &*& operator is the separating conjunction โ integer(p, v) &*& integer(q, w) asserts that p and q point to distinct integers with values v and w. The postcondition asserts the swap has occurred and the two permissions are returned.
For Java, specifications use /*@ ... @*/ blocks:
/*@ requires integer(p.value, ?v) &*& p != null;
@ ensures integer(p.value, v + 1);
@*/
void increment(Counter p) {
p.value++;
}
Heap Predicates
VeriFast defines several built-in predicates for common heap structures:
integer(p, v) โ pointer p holds the integer value v. Full (exclusive) ownership: reading and writing permitted.
// Reading requires and produces integer permission
int read(int *p)
//@ requires integer(p, ?v);
//@ ensures integer(p, v) &*& result == v;
{ return *p; }
chars(p, n, cs) โ n characters starting at pointer p form the list cs. Used for string and byte-array reasoning.
void zero_fill(char *buf, int n)
//@ requires chars(buf, n, _);
//@ ensures chars(buf, n, repeat('\0', n));
{ for (int i = 0; i < n; i++) buf[i] = '\0'; }
malloc_block(ptr, n) โ the heap block at ptr was allocated with size n and may be freed. VeriFast tracks allocation ownership statically โ free(ptr) requires malloc_block(ptr, n) &*& ... in the precondition, preventing double-free and use-after-free by proof.
int *alloc_int(int v)
//@ requires true;
//@ ensures malloc_block(result, sizeof(int)) &*& integer(result, v);
{
int *p = malloc(sizeof(int));
//@ assume(p != 0);
*p = v;
return p;
}
Abstract Predicates โ open/close
User-defined predicates encapsulate heap invariants for data structures. A linked list node owns its data and the recursive tail:
/*@
predicate node(struct Node *n; int val, list<int> rest) =
n != 0 &*& n->val |-> val &*& n->next |-> ?nxt &*&
(nxt == 0 ? rest == nil : node(nxt, _, ?t) &*& rest == cons(_, t));
@*/
The open and close commands fold and unfold predicates during symbolic execution โ analogous to Viper's fold/unfold:
void push(struct Node **head, int v)
//@ requires *head |-> ?h &*& (h == 0 ? true : node(h, _, _));
//@ ensures *head |-> ?newh &*& node(newh, v, _);
{
struct Node *n = malloc(sizeof(struct Node));
n->val = v;
n->next = *head;
*head = n;
//@ close node(n, v, _);
}
Fractional Permissions โ Shared Read Access
VeriFast supports fractional permissions for concurrent read sharing. A fractional permission [1/2]integer(p, v) grants read-only access with half ownership โ two threads can each hold [1/2] for a total of [1/1] (full ownership):
// Reader: requires [1/2] permission, returns same fraction
int read_shared(int *p)
//@ requires [1/2]integer(p, ?v);
//@ ensures [1/2]integer(p, v) &*& result == v;
{ return *p; }
// Writer: requires full [1/1] permission
void write_exclusive(int *p, int v)
//@ requires integer(p, _);
//@ ensures integer(p, v);
{ *p = v; }
This models the standard reader/writer discipline: multiple readers can coexist (each holds a fraction), but a writer requires exclusive ownership (sum of all fractions = 1). The permission model prevents data races by proof โ no dynamic race detector, no runtime overhead.
Lemma Functions โ Ghost Code
Lemma functions contain ghost code: proof steps that have no runtime execution but establish logical facts used in verification. They allow inductive reasoning about recursive data structures:
/*@
lemma void list_length_nonneg(list<int> xs)
requires true;
ensures length(xs) >= 0;
{
switch (xs) {
case nil: break;
case cons(h, t): list_length_nonneg(t); break;
}
}
@*/
Lemmas are verified against their own pre/postconditions. Calling a lemma in a proof context is safe because its correctness is machine-checked โ no axiom gaps. This allows complex data structure invariants (red-black trees, AVL trees, circular buffers) to be verified modularly.
Inductive Datatypes and Fixpoint Functions
VeriFast's ghost language includes ML-style inductive datatypes and fixpoint functions for pure recursive computation over heap structures:
/*@
inductive intlist = nil | cons(int, intlist);
fixpoint int sum(intlist xs) {
switch (xs) {
case nil: return 0;
case cons(h, t): return h + sum(t);
}
}
fixpoint intlist append(intlist xs, intlist ys) {
switch (xs) {
case nil: return ys;
case cons(h, t): return cons(h, append(t, ys));
}
}
@*/
These datatypes appear in predicate definitions and specifications, enabling fully verified algorithms over recursive structures โ linked lists, trees, graphs โ without approximation.
Java Verification
VeriFast supports Java programs with the same specification language adapted to object-oriented idioms. Class invariants, interface contracts, and inheritance are handled via Java-specific predicates:
/*@
predicate Counter_valid(Counter c; int v) =
c.value |-> v &*& v >= 0;
@*/
class Counter {
int value;
/*@ requires Counter_valid(this, ?v);
@ ensures Counter_valid(this, v + 1);
@*/
void increment() {
value++;
}
/*@ requires Counter_valid(this, ?v);
@ ensures Counter_valid(this, 0);
@*/
void reset() {
value = 0;
}
}
Java interfaces get verified contracts that all implementing classes must satisfy โ enabling compositional verification of object-oriented systems where implementations are verified independently of callers.
Industrial Applications โ Medical Devices and Automotive
VeriFast targets the safety-critical embedded software ecosystem where C dominates:
IEC 62304 (Medical Device Software) โ the EU Medical Device Regulation (MDR 2017/745) mandates lifecycle safety for software in Class IIb and III medical devices. VeriFast-verified C libraries for signal processing (ECG algorithms, insulin pump control, infusion pump logic) provide machine-checked freedom from memory errors โ zero null dereferences, zero buffer overflows, zero use-after-free โ as formal evidence for IEC 62304 compliance artifacts. Belgian medtech companies (e.g., Agfa HealthCare ๐ง๐ช, Materialise ๐ง๐ช) develop embedded C software on KU Leuven's doorstep.
AUTOSAR and ISO 26262 โ automotive Basic Software (BSW) modules written in AUTOSAR Classic C (MCAL layers, COM/RTE stacks) are natural VeriFast targets. ISO 26262 ASIL D demands exhaustive evidence for absence of systematic software faults; VeriFast separation logic proofs provide this evidence for memory safety properties โ pointer arithmetic, DMA buffer ownership, interrupt handler isolation โ that neither static analysis nor testing can exhaust.
IMEC / imec ๐ง๐ช (Holst Centre, Leuven) โ Europe's leading nanoelectronics research institute, adjacent to KU Leuven, develops C firmware for energy-harvesting sensor nodes, IoT edge processors, and medical implantables. VeriFast has been used in imec projects for verifying C-based protocol stacks on microcontrollers where heap usage must be precisely bounded.
EU Ecosystem Position
VeriFast occupies a distinctive position in the EU formal verification landscape:
| Tool | Origin | Language | Approach |
|---|---|---|---|
| VeriFast | KU Leuven ๐ง๐ช | C, Java | Separation logic + symbolic execution |
| Frama-C/WP | CEA/INRIA ๐ซ๐ท | C | ACSL + weakest preconditions + Why3 |
| KeY | TU Darmstadt ๐ฉ๐ช + KIT ๐ฉ๐ช | Java | Dynamic Logic + sequent calculus |
| Prusti | ETH Zurich ๐จ๐ญ | Rust | Viper/IDF + Silicon/Z3 |
| Gobra | ETH Zurich ๐จ๐ญ | Go | Viper/IDF + Silicon/Z3 |
| Nagini | ETH Zurich ๐จ๐ญ | Python | Viper/IDF + Silicon/Z3 |
VeriFast's separation logic approach directly inspired the Implicit Dynamic Frames (IDF) model used in Viper (ETH Zurich ๐จ๐ญ, VMCAI 2016) โ the infrastructure behind Prusti, Gobra, and Nagini. The conceptual lineage runs: Reynolds/O'Hearn separation logic โ VeriFast (KU Leuven ๐ง๐ช, 2008) โ Viper IDF (ETH Zurich ๐จ๐ญ, 2016) โ Prusti/Gobra/Nagini front-ends. All EU institutions, all publicly funded, all building on each other's research.
EU Regulatory Alignment
EU AI Act Art. 9 (Technical Documentation for High-Risk Systems): VeriFast-verified C inference code (neural network forward passes, signal classifiers, medical decision support) provides machine-checked functional correctness certificates โ preconditions define valid input domains, postconditions bound output ranges, separation logic proofs guarantee memory isolation between patient data records.
EU AI Act Art. 10 (Data Governance): VeriFast separation logic proofs on C data processing pipelines demonstrate that memory regions containing personal health data are accessed only through verified accessors โ no pointer arithmetic bypasses the separation logic frame conditions.
GDPR Art. 25 (Data Protection by Design): malloc_block ownership tracking proves that dynamically allocated patient records are freed exactly once and not readable after deallocation โ no dangling pointer access to personal data is possible under the verified execution model.
Cyber Resilience Act (CRA, 2027): CRA Article 13 requires manufacturers of products with digital elements to document that products are designed and developed without known exploitable vulnerabilities. VeriFast proofs for C libraries provide formal evidence for memory safety (no buffer overflow, no use-after-free, no double-free) โ the root cause of the majority of CVEs in C-based embedded systems.
IEC 62304 Class C Software: VeriFast-verified C module test evidence complements unit tests for medical device software classification, satisfying the "software safety requirements specification" traceability requirement.
Deploy VeriFast on EU Infrastructure with sota.io
VeriFast runs on Java (JVM), requires no cloud connectivity during verification, and produces verification reports locally. Deploy a VeriFast-integrated C/Java CI pipeline on sota.io โ the EU-native PaaS on German infrastructure, GDPR-compliant by default, with managed PostgreSQL for storing verification audit trails:
# Install VeriFast
wget https://github.com/verifast/verifast/releases/latest/download/verifast-linux.tar.gz
tar xf verifast-linux.tar.gz
export PATH=$PATH:$(pwd)/verifast/bin
# Verify a C file
verifast -c mylib.c
# Verify all C files in project
find src/ -name "*.c" | xargs verifast -c
sota.io provides:
- EU data residency โ verification logs, audit trails, and build artifacts stay in Germany. No US Cloud Act exposure.
- Managed PostgreSQL โ store VeriFast verification results, proof obligation statistics, and historical correctness evidence per commit.
- Zero DevOps โ push your VeriFast CI container and sota.io handles deployment, scaling, and PostgreSQL backups.
- GDPR compliance โ data processed in EU jurisdiction, no transatlantic transfer for verification artifacts of medical or automotive code.
# sota.io deploy
sota deploy --region eu-central
Free tier available. No credit card required to start.
See Also
- Deploy Prusti to Europe โ โ Viper-based Rust verifier (ETH Zurich ๐จ๐ญ), permission logic for Rust ownership
- Deploy Gobra to Europe โ โ Viper-based Go verifier (ETH Zurich ๐จ๐ญ), goroutine/channel separation logic
- Deploy Nagini to Europe โ โ Viper-based Python verifier (ETH Zurich ๐จ๐ญ), thread safety verification
- Deploy Viper to Europe โ โ Permission-based IVL (ETH Zurich ๐จ๐ญ), the backend powering Prusti, Gobra, and Nagini
- Deploy Frama-C to Europe โ โ EU-native C verifier (CEA/INRIA ๐ซ๐ท), ACSL + weakest preconditions
- Deploy KeY to Europe โ โ EU-native Java verifier (TU Darmstadt ๐ฉ๐ช + KIT ๐ฉ๐ช), dynamic logic + JML