Program Verification via an Intermediate Verification Language

Slides:



Advertisements
Similar presentations
Advanced programming tools at Microsoft
Advertisements

Joint work with Mike Barnett, Robert DeLine, Manuel Fahndrich, and Wolfram Schulte Verifying invariants in object-oriented programs K. Rustan M. Leino.
Extended Static Checking for Java Cormac Flanagan K. Rustan M. Leino Mark Lillibridge Greg Nelson James B. Saxe Raymie Stata Compaq SRC 18 June 2002 PLDI02,
The Spec# programming system K. Rustan M. Leino Microsoft Research, Redmond, WA, USA Lunch seminar, Praxis Bath, UK 6 Dec 2005 joint work with Mike Barnett,
Demand-driven inference of loop invariants in a theorem prover
Object Invariants in Specification and Verification K. Rustan M. Leino Microsoft Research, Redmond, WA Joint work with: Mike Barnett, Ádám Darvas, Manuel.
Writing specifications for object-oriented programs K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 21 Jan 2005 Invited talk, AIOOL 2005 Paris,
1 Towards a Verifying Compiler: The Spec# Approach Wolfram Schulte Microsoft Research Formal Methods 2006 Joint work with Rustan Leino, Mike Barnett, Manuel.
Program Verification Using the Spec# Programming System ETAPS Tutorial K. Rustan M. Leino, Microsoft Research, Redmond Rosemary Monahan, NUIM Maynooth.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 1 Summer school on Formal Models.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 0 Summer school on Formal Models.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Challenges in increasing tool support for programming K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 23 Sep 2004 ICTAC Guiyang, Guizhou, PRC joint.
Using SMT solvers for program analysis Shaz Qadeer Research in Software Engineering Microsoft Research.
Synthesis, Analysis, and Verification Lecture 04c Lectures: Viktor Kuncak VC Generation for Programs with Data Structures “Beyond Integers”
Automated Software Verification with a Permission-Based Logic 20 th June 2014, Zürich Malte Schwerhoff, ETH Zürich.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA, USA 3 December 2008 U. Lugano Lugano, Switzerland.
ISBN Chapter 3 Describing Syntax and Semantics.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 0 International Summer School Marktoberdorf Marktoberdorf,
ECI 2007: Specification and Verification of Object-Oriented Programs Lecture 2 Courtesy: K. Rustan M. Leino and Wolfram Schulte.
Lecture 2 Towards a Verifying Compiler: Logic of Object oriented Programs Wolfram Schulte Microsoft Research Formal Methods 2006 Objects, references, heaps,
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 1 LASER.
Hoare-style program verification K. Rustan M. Leino Guest lecturer Rob DeLine’s CSE 503, Software Engineering University of Washington 26 Apr 2004.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 0 Summer School on Logic and Theorem-Proving in Programming.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 0 LASER.
ECI 2007: Specification and Verification of Object- Oriented Programs Lecture 1.
Building a program verifier K. Rustan M. Leino Microsoft Research, Redmond, WA 10 May 2006 Guest lecture, Shaz Qadeer’s cse599f, Formal Verification of.
K. Rustan M. Leino Microsoft Research, Redmond NUI Maynooth Maynooth, Ireland 8 June 2007.
Well-cooked Spaghetti: Weakest-Precondition of Unstructured Programs Mike Barnett and Rustan Leino Microsoft Research Redmond, WA, USA.
Chair of Software Engineering Automatic Verification of Computer Programs.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 5 LASER.
Describing Syntax and Semantics
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 3 LASER.
K. Rustan M. Leino Microsoft Research, Redmond, WA 10 Oct 2007 IFIP WG 2.3 meeting Santa Fe, NM.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Caltech Pasadena, CA 12 November 2009.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 1 Summer School on Logic and Theorem-Proving in Programming.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 3 Marktoberdorf.
Viper A Verification Infrastructure for Permission-Based Reasoning 1 st March 2015, ECOOP’15 PC Meeting, Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,
Program Verification K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond University of Washington CSE P January.
Viper A Verification Infrastructure for Permission-Based Reasoning 24 th March 2015, JML Workshop, Leiden Uri Juhasz, Ioannis Kassios, Peter Müller, Milos.
Reasoning about programs March CSE 403, Winter 2011, Brun.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 0 Marktoberdorf.
Chapter 3 Part II Describing Syntax and Semantics.
Spec# Andreas Vida. Motivation Correct and maintainable software Correct and maintainable software Cost effective software production Cost effective software.
Specifying and verifying programs in Spec# K. Rustan M. Leino Microsoft Research, Redmond, WA, USA Invited talk, PSI 2006 Novosibirsk, Russia 27 June 2006.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 2 International Summer School Marktoberdorf Marktoberdorf,
K. Rustan M. Leino RiSE, Microsoft Research, Redmond joint work with Peter Müller and Jan Smans Lecture 1 2 September 2009 FOSAD 2009, Bertinoro, Italy.
K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 15 Nov 2007 Chalmers Göteborg, Sweden.
Boolean Programs: A Model and Process For Software Analysis By Thomas Ball and Sriram K. Rajamani Microsoft technical paper MSR-TR Presented by.
Dafny An automatic program verifier for functional correctness
Automated program verification Bryan Parno
Specification techniques for verifying object-oriented software
Auto-active verification
Weakest Precondition of Unstructured Programs
Further with Hoare Logic Sections 6.12, 6.10, 6.13
A Verification Infrastructure for Permission-based Reasoning
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Hoare-style program verification
Auto-active verification
Lecture 5 Floyd-Hoare Style Verification
Programming Languages and Compilers (CS 421)
Hoare-style program verification
Semantics In Text: Chapter 3.
Dafny An automatic program verifier for functional correctness
Predicate Transformers
Auto-active verification
The Zoo of Software Security Techniques
Programming Languages and Compilers (CS 421)
Presentation transcript:

Program Verification via an Intermediate Verification Language K. Rustan M. Leino Principal Researcher Research in Software Engineering (RiSE), Microsoft Research, Redmond Visiting Professor Department of Computing, Imperial College London Guest lecture in Emina Torlak’s CSE 507, Computer-Aided Reasoning for Software 4 May 2016, UW, Seattle, WA, USA

Static program verification What is the state-of-art in program verifiers? How to build a program verifier

Dafny Put reasoning about programs first Language aimed at reasoning Constructs for recording design decisions Tool support Static program verifier enforces design decisions Integrated development environment Tools help in reasoning process Verification is not an afterthought

Demo Imperative programs: Queue implemented by a ring buffer data: (start + count) % data.Length Demo start data: Enqueue at (start + count) % data.Length Dequeue at start Imperative programs: Queue implemented by a ring buffer

Copying into the new array start data: more start d:

Separation of concerns Intermediate verification language Intermediate representation Compiler Verifier SMT solver

Verification architecture Dafny Boogie SMT solver

Boogie Verification Debugger Meet the family GPU Verify … STORM (C) Boogie x86 QED C B Analyze Corral Poirot Forró Diego-matic Spec# VCC (C) HAVOC (C) Dafny Chalice Eiffel (EveProofs) Java BML Region Logic Boogie Boogie Verification Debugger inference SymDiff SMT Lib Z3 TPTP

Verification architecture Hi-Lite Ada Frama-C Pangoline Who Jessie Krakatoa CAO Why3 Alt-Ergo … SMT Lib Z3 Coq Isabelle/HOL CVC 3

Boogie language overview Mathematical features type T const x… function f… axiom E Imperative features var y… procedure P… …spec… implementation P… { …body… }

Statement outcomes Terminate Go wrong Block Diverge

Boogie statements x := E a[i] := E havoc x assert E assume E call P() Evaluate E and change x to that value a[i] := E Same as a := a[i := E] havoc x Change x to an arbitrary value assert E If E holds, terminate; otherwise, go wrong assume E If E holds, terminate; otherwise, block call P() Act according to specification of P if while break label: goto A, B

Translation basics Ada Boogie var x: int; procedure Update(y: int) returns (r: int) modifies x; { if (x < y) { x := y; } r := y; procedure Main() call x := Update(5); x : Integer; procedure Update (y : Integer; r : out Integer) is begin if x < y then x := y; end if; r := y; end Update; procedure Main is Update(5, x); end Main;

Unstructured control flow .NET bytecode (MSIL) Boogie var i: int, CS$4$000: bool; var $stack0i, $stack1i: int, $stack0b: bool; IL_0000: $stack0i := 0; i := 0; goto IL_000b; IL_0005: $stack1i := i; $stack0i := $stack0i + $stack1i; i := $stack0i; IL_000b: $stack0i := i; $stack1i := n; $stack0b := $stack0i < $stack1i; CS$4$000 := $stack0b; $stack0b := CS$4$000; if ($stack0b) { goto IL_0005; } IL_0013: return; .maxstack 2 .locals init ([0] int32 i, [1] bool CS$4$0000) IL_0000: nop IL_0001: ldc.i4.0 IL_0002: stloc.0 IL_0003: br.s IL_000b IL_0005: nop IL_0006: ldloc.0 IL_0007: ldc.i4.1 IL_0008: add IL_0009: stloc.0 IL_000a: nop IL_000b: ldloc.0 IL_000c: ldarg.0 IL_000d: clt IL_000f: stloc.1 IL_0010: ldloc.1 IL_0011: brtrue.s IL_0005 IL_0013: ret

Reasoning about loops Java + JML Boogie //@ requires 0 <= n; void m(int n) { int i = 0; //@ loop_invariant i <= n; while (i < n) { i++; } //@ assert i == n; procedure m(n: int) requires 0 <= n; { var i: int; i := 0; while (i < n) invariant i <= n; i := i + 1; } assert i == n;

Custom operators: underspecification Boogie const Two^31: int; axiom Two^31 == 2147483648; function LeftShift(int, int): int; axiom (forall a: int :: LeftShift(a, 0) == a); function Add(int, int): int; axiom (forall a, b: int :: -Two^31 <= a+b && a+b < Two^31 ==> Add(a,b) == a+b); procedure P() { var x: int; x := LeftShift(y, z); x := Add(y, z); } void P() { int x; x = y << z; x = y + z; }

Definedness of expressions Boogie let x = y + z in let w = y / z in // ... // check for underflow: assert -Two^31 <= y+z; // check for overflow: assert y+z < Two^31; x := y + z; // check division by zero: assert z != 0; w := Div(y, z);

Uninitialized variables Pascal Boogie var r: integer; if B then r := z; (* ... *) if C then begin d := r end var r: int; var r$defined: bool; if (B) { r, r$defined := z, true; } // ... if (C) { assert r$defined; d := r; }

Loop termination Eiffel Boogie from Init until B invariant Inv variant VF loop Body end Init; while (!B) invariant Inv; // check boundedness: invariant 0 <= VF; { tmp := VF; Body; // check decrement: assert VF < tmp; }

Modeling memory C# Boogie class C { C next; void M(C c) { C x = next; type Ref; const null: Ref; type Field; const unique C.next: Field; var Heap: [Ref,Field]Ref; // Ref * Field --> Ref procedure C.M(this: Ref, c: Ref) requires this != null; modifies Heap; { var x: Ref; assert this != null; x := Heap[this, C.next]; assert c != null; Heap[c, C.next] := y; } class C { C next; void M(C c) { C x = next; c.next = c; }

More about memory models Encoding a good memory model requires more effort Boogie provides many useful features Polymorphic map types Partial commands (assume statements) Free pre- and postconditions where clauses

Demo RingBuffer translated

Verification-condition generation 0. passive features: assert, assume, ; 1. control flow: goto (no loops) 2. state changes: :=, havoc 3. loops

Weakest preconditions The weakest precondition of a statement S with respect to a predicate Q on the post-state of S, denoted wp(S,Q), is the set of pre-states from which execution: does not go wrong, and if it terminates, terminates in Q

VC generation: passive features wp( assert E, Q ) = E  Q wp( assume E, Q ) = E  Q wp( S; T, Q ) = wp( S, wp( T, Q ))

VC generation: acyclic control flow For each block A, introduce a variable Aok with the meaning: Aok is true iff every program execution starting in the current state from block A does not go wrong The verification condition for the program: A: S; goto B or C … is: ( Aok  wp( S, Bok  Cok ) )   Aok

VC generation: state changes Replace definitions and uses of variables by definitions and uses of different incarnations of the variables {xx0, yy0} x := E(x,y) x1 := E(x0,y0) {xx1, yy0} {xx0, yy0} havoc x skip {xx1, yy0}

VC generation: state changes (cont.) Given: {xx0 ,yy0} S S’ {xx1, yy0} {xx0, yy0} T T’ {xx2, yy0} then we have: {xx0, yy0} if E(x,y) then S else T end if E(x0,y0) then S’ ; x3 := x1 else T’ ; x3 := x2 end {xx3, yy0}

VC generation: state changes (cont.) Replace every assignment x := E with assume x = E

VC generation: loops assert LoopInv( x ) ; assume Guard( x ) ; x := … loop head: assert LoopInv( x ) ; assume Guard( x ) ; x := … after loop: loop body: assume ¬Guard( x ) ;

assert P = assert P ; assume P VC generation: loops assert P = assert P ; assume P loop head: assert LoopInv( x ) ; assume LoopInv( x ); assume Guard( x ) ; x := … after loop: loop body: assume ¬Guard( x ) ;

VC generation: loops assert LoopInv( x ) ; loop head: assert LoopInv( x ) ; assume LoopInv( x ); assume Guard( x ) ; x := … after loop: loop body: assume ¬Guard( x ) ; assert LoopInv( x ) ;

VC generation: loops loop target assert LoopInv( x ) ; havoc x ; loop head: havoc x ; assume LoopInv( x ); loop target assume Guard( x ) ; x := … assert LoopInv( x ); after loop: loop body: assume ¬Guard( x ) ;

VC generation: loops assert LoopInv( x ) ; havoc x ; loop head: havoc x ; assume LoopInv( x ); assume Guard( x ) ; x := … assert LoopInv( x ); assume false; after loop: loop body: assume ¬Guard( x ) ;

Demo /traceverify

Take-home messages To build a verifier, use an intermediate verification language (IVL) An IVL is a thinking tool An IVL helps you separate concerns IVL lets you reuse and share infrastructure Try Dafny and Boogie in your browser at rise4fun.com Watch Verification Corner on YouTube