Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201

Slides:



Advertisements
Similar presentations
1 Lecture 5 Towards a Verifying Compiler: Multithreading Wolfram Schulte Microsoft Research Formal Methods 2006 Race Conditions, Locks, Deadlocks, Invariants,
Advertisements

Joint work with Mike Barnett, Robert DeLine, Manuel Fahndrich, and Wolfram Schulte Verifying invariants in object-oriented programs K. Rustan M. Leino.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 3 Summer school on Formal Models.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Lecture 4 Towards a Verifying Compiler: Data Abstraction Wolfram Schulte Microsoft Research Formal Methods 2006 Purity, Model fields, Inconsistency _____________.
Semantics Static semantics Dynamic semantics attribute grammars
Introducing Formal Methods, Module 1, Version 1.1, Oct., Formal Specification and Analytical Verification L 5.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Constraint Semantics for Abstract Read Permissions 28 th July 2014, FTfJP, Uppsala John Tang Boyland (UW-Milwaukee/ETH Zurich) Peter Müller, Malte Schwerhoff,
Reduction, abstraction, and atomicity: How much can we prove about concurrent programs using them? Serdar Tasiran Koç University Istanbul, Turkey Tayfun.
Automated Software Verification with a Permission-Based Logic 20 th June 2014, Zürich Malte Schwerhoff, ETH Zürich.
Verification of Multithreaded Object- Oriented Programs with Invariants Bart Jacobs, K. Rustan M. Leino, Wolfram Schulte.
A simple sequential reasoning approach for sound modular verification of mainstream multithreaded programs Wolfram Schulte & Bart Jacobs Microsoft Research.
Chair of Software Engineering The alias calculus Bertrand Meyer ITMO Software Engineering Seminar June 2011.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA, USA 3 December 2008 U. Lugano Lugano, Switzerland.
Changing perspective can be useful Relating alternative logics for automatic software verification Alex Summers (ETH Zurich) partly based on joint work.
Fractional Permissions without the Fractions Alex Summers ETH Zurich Joint work with: Stefan Heule, Rustan Leino, Peter Müller ETH Zurich MSR Redmond ETH.
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,
VIDE Integrated Environment for Development and Verification of Programs.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 0 Summer School on Logic and Theorem-Proving in Programming.
On the Relationship Between Concurrent Separation Logic and Assume-Guarantee Reasoning Xinyu Feng Yale University Joint work with Rodrigo Ferreira and.
Building a program verifier K. Rustan M. Leino Microsoft Research, Redmond, WA 10 May 2006 Guest lecture, Shaz Qadeer’s cse599f, Formal Verification of.
Extensible Untrusted Code Verification Robert Schneck with George Necula and Bor-Yuh Evan Chang May 14, 2003 OSQ Retreat.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Caltech Pasadena, CA 12 November 2009.
K. Rustan M. Leino RiSE, Microsoft Research, Redmond joint work with Peter Müller and Jan Smans Lecture 0 1 September 2009 FOSAD 2009, Bertinoro, Italy.
K. Rustan M. Leino RiSE, Joint work with: Peter Müller (ETH Zurich) Jan Smans (KU Leuven) Special thanks to Mike Barnett VMCAI, Madrid, Spain, 18 January.
Formal Methods 1. Software Engineering and Formal Methods  Every software engineering methodology is based on a recommended development process  proceeding.
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
Automated Software Verification with Implicit Dynamic Frames 5 th December 2013, Leuven Malte Schwerhoff, ETH Zürich/KU Leuven.
Viper A Verification Infrastructure for Permission-Based Reasoning 1 st March 2015, ECOOP’15 PC Meeting, Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,
Formal Verification Lecture 9. Formal Verification Formal verification relies on Descriptions of the properties or requirements Descriptions of systems.
Viper A Verification Infrastructure for Permission-Based Reasoning 24 th March 2015, JML Workshop, Leiden Uri Juhasz, Ioannis Kassios, Peter Müller, Milos.
Rustan Leino RiSE, Microsoft Research, Redmond MIT 5 June 2009 Joint work with: Peter Müller, ETH Zurich Jan Smans, KU Leuven.
A Universe-Type-Based Verification Technique for Mutable Static Fields and Methods Alexander J Summers Sophia Drossopoulou Imperial College London Peter.
Reasoning about programs March CSE 403, Winter 2011, Brun.
Automated and Modular Refinement Reasoning for Concurrent Programs Shaz Qadeer.
Lightweight Support for Magic Wands in an Automatic Verifier Malte Schwerhoff and Alexander J. Summers 10 th July 2015, ECOOP, Prague.
An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems Group, ETH Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,
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.
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
ESOP 2010, Paphos, Cyprus, 22 March 2010 K. Rustan M. Leino (RiSE group, Microsoft Research) Peter Müller (ETH Zurich) Jan Smans (KU Leuven)
Faithful mapping of model classes to mathematical structures Ádám Darvas ETH Zürich Switzerland Peter Müller Microsoft Research Redmond, WA, USA SAVCBS.
VPERM: Variable Permissions for Concurrency Verification Duy-Khanh Le, Wei-Ngan Chin, Yong-Meng Teo ICFEM, Kyoto, Japan, Nov 2012.
NIRICT RECONNAISSANCE TOPIC PERFORMANCE AND CORRECTNESS OF GPGPU MARIEKE HUISMAN ALEXANDRU IOSUP ANA LUCIA VARBANESCU ANTON WIJS.
Spring 2017 Program Analysis and Verification
Dafny An automatic program verifier for functional correctness
Further with Hoare Logic Sections 6.12, 6.10, 6.13
A Verification Infrastructure for Permission-based Reasoning
The Relationship Between Separation Logic and Implicit Dynamic Frames
Matching Logic An Alternative to Hoare/Floyd Logic
The Relationship Between Separation Logic and Implicit Dynamic Frames
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Graph-Based Operational Semantics
Joint work with Yong Li, Xinyu Feng, Zhong Shao and Yu Zhang
(One-Path) Reachability Logic
Automating Induction for Solving Horn Clauses
Modular Verification of Message Passing Programs
Verification of Concurrent Programs
Verification of concurrent object-oriented programs
Matching Logic - A New Program Verification Approach -
IS 2935: Developing Secure Systems
Programming Languages 2nd edition Tucker and Noonan
A Verification Infrastructure for Permission-Based Reasoning
Threads and Memory Models Hal Perkins Autumn 2009
Dafny An automatic program verifier for functional correctness
Language-Independent Verification Framework
Programming Languages 2nd edition Tucker and Noonan
A Considerate Specification of the Composite Pattern
Presentation transcript:

Deductive Verification Tools Tutorial for Dagstuhl Seminar 16201 while(i>0) { i--; }  …………  …………  ………… Note: slide numbers 18th May 2016 Alexander J. Summers ETH Zurich, Switzerland

Deductive Verification Tools while(i>0) { i--; } Take a program

Deductive Verification Tools while(i>0) { i--; }  …………  …………  ………… spec Take a program annotated with some specifications Automate a reasoning technique to find proof / errors typically: consider each program point only once This part of the tutorial: example deductive verification tools and their use how to construct new ones Not here: static analysers, proof assistants, …

Deductive Verification Tools full software stack for secure remote apps safety, liveness, functionality of distributed systems Java concurrency, GPU software, kernel code Ironclad IronFleet VerCors VCC Chalice VeriFast C and Java code (e.g. Linux device driver, Java Card) C code (e.g. MS Hypervisor) Race-free OO concurrency features (PL) Viper Intermediate Verification Language (more later…)

Concurrency Reasoning Ingredients Ironclad IronFleet VerCors VCC Chalice VeriFast Invariants (per object / thread) Two-state (transition) invariants count <= old(count) Methodology for local verification Ownership as auxiliary state Other reasoning encodable e.g. claims for shared access Viper

Concurrency Reasoning Ingredients Ironclad IronFleet VerCors VCC Chalice VeriFast Separation logic (for ownership) x.count ↦ 4 Reasoning Libraries (e.g. monitors) Shared Boxes with invariants (rely-guarantee reasoning) Lemma function pointers (ghost state maintenance) Viper

Concurrency Reasoning Ingredients Ironclad IronFleet VerCors VCC Chalice VeriFast Access permissions (ownership) acc(x.count) Fractional permissions (sharing) Modular lock ordering specification (deadlock avoidance) Two-state monitor/lock invariants (CSL, plus some rely-guarantee) Viper

Demo (Owicki-Gries in Chalice) class OwickiGries { requires rd(mu) && waitlevel << mu // may acquire lock var count: int ghost var g0: int requires (b ? acc(this.g0,50) : acc(this.g1,50)) ghost var g1: int ensures b ==> acc(this.g0,50) && this.g0 == old(this.g0) + 1 invariant acc(this.count) && acc(this.g0,50) ensures !b ==> acc(this.g1,50) && this.g1 == old(this.g1) + 1 && acc(this.g1,50) && this.count == this.g0 + this.g1 ensures rd(mu) { method Main() { acquire(this) var og := new OwickiGries{ count := 0, g0 :=0, g1 := 0 } this.count := this.count + 1 if(b) { share og // monitor available this.g0 := this.g0 + 1 } else { fork tk0 := og.Worker(false) this.g1 := this.g1 + 1 fork tk1 := og.Worker(true) join tk0; join tk1 release(this) acquire og; unshare og assert og.count == 2 http://rise4fun.com/Chalice } method Worker(b: bool) http://chalice.codeplex.com/

Tool Design We did not develop a step-by-step proof provide only the essence of the formal argument What is this essence? which assertions are essential information? modularity? to abstract control flow? which proof steps user directed (not syntactically)? which reasoning ingredients are natively supported? How can these ingredients be implemented? Option 1: implement custom support (hard) Option 2: design an encoding using an existing tool often: find a different way to model same idea Only sound if x.next will not be modified in future

Example: modelling ownership transfer Partial heaps 4 inv 3 count 1 acquire (this) // Inhale the monitor invariant count := count + 1 …

Example: modelling ownership transfer Partial heaps 4 inv 3 count 2 acquire (this) // Inhale the monitor invariant count := count + 1 … release(this) // Exhale the monitor invariant

Example: modelling ownership transfer Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 1 1 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 … release(this) // Exhale the monitor invariant

Example: modelling ownership transfer Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 … release(this) // Exhale the monitor invariant

Implementing the reasoning Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 maintain “heap chunks” in tool Add/remove for inhale/exhale Abstract over concrete values Value reasoning via SMT solver Symbolic execution (e.g. VeriFast) generate instrumented program track permissions as auxiliary state keep some heap values consistent Encode resulting program (Boogie) Embed proof obligations (e.g. Chalice)

Building up tool stacks… Ironclad IronFleet VerCors VCC Chalice VeriFast Dafny Viper Encoding to express sufficient proof obligations (somehow) Encoding need not preserve operational semantics May involve auxiliary state, indirect modelling of features (Very) useful: support for desired reasoning ingredients Boogie Z3

Example: modelling ownership transfer Partial heaps Total heaps + accounting 3 4 4 inv inv 3 count 3 count 2 2 2 4 7 acquire (this) // Inhale the monitor invariant count := count + 1 … release(this) // Exhale the monitor invariant // inhale / gain ownership assert Mask[this,count] == 1 Heap[this,count]++ Mask[this.count]-- // exhale / release ownership

Demo 2 (encoding Chalice in Viper) class OwickiGries { var count: int ghost var g0: int ghost var g1: int invariant acc(this.count) && acc(this.g0,50) && acc(this.g1,50) && this.count == this.g0 + this.g1 method Main() { var og := new OwickiGries{ count := 0, g0 :=0, g1 := 0 } share og // monitor available fork tk0 := og.Worker(false) fork tk1 := og.Worker(true) join tk0; join tk1 acquire og; unshare og assert og.count == 2 } method Worker(b: bool) requires rd(mu) && waitlevel << mu // may acquire lock requires (b ? acc(this.g0,50) : acc(this.g1,50)) ensures b ==> acc(this.g0,50) && this.g0 == old(this.g0) + 1 ensures !b ==> acc(this.g1,50) && this.g1 == old(this.g1) + 1 ensures rd(mu) { acquire(this) this.count := this.count + 1 if(b) { this.g0 := this.g0 + 1 } else { this.g1 := this.g1 + 1 release(this) http://viper.ethz.ch/examples/blank-example.html http://viper.ethz.ch/ field count: Int field g0: Int field g1: Int // monitor invariant define inv (acc(og.count) && acc(og.g0,1/2) && acc(og.g1,1/2) && og.count == og.g0 + og.g1) method Main() { var og : Ref; og := new(count,g0,g1); // specify the fields which the object has og.count := 0; og.g0 := 0; og.g1 := 0; // share monitor: exhale invariant exhale inv // fork first thread := Worker(og,true) (uses g0 ghost variable) label l0 exhale acc(og.g0,1/2) // fork second thread := Worker(og,false) (uses g1 ghost variable) label l1 exhale acc(og.g1,1/2) // join thread 0 (Worker(og,true)) inhale acc(og.g0,1/2) && og.g0 == old[l0](og.g0) + 1 // join thread 1 (Worker(og,false)) inhale acc(og.g1,1/2) && og.g1 == old[l1](og.g1) + 1 // acquire the monitor (for remaining permissions) - can be unshared in source program inhale inv assert og.count == 2 } method Worker(og:Ref, b:Bool) // mu-related deadlock checking: omitted requires (b ? acc(og.g0,1/2) : acc(og.g1,1/2)) ensures (b ==> acc(og.g0,1/2) && og.g0 == old(og.g0) + 1) ensures (!b ==> acc(og.g1,1/2) && og.g1 == old(og.g1) + 1) { og.count := og.count + 1 if(b) { og.g0 := og.g0 + 1 } else { og.g1 := og.g1 + 1

The Viper Project Viper IVL We have designed a new intermediate verification language Reusable, native support for various common reasoning ingredients e.g. permissions, inhale/exhale Idea: front-end tools that encode a problem into a Viper program We provide (two) Viper Verifiers In use for several projects (later): Developing full-blown verifiers Hand-coding examples Building prototypes quickly Program + properties Viper IVL Viper Verifiers Automatic Provers etc. ✔ ✘

Viper: a toolbox for concurrency verification Object-based (but not OO – no classes/inheritance) Declarations: fields, methods, predicates, functions Statements: assignments, loops, calls, inhale/exhale loops have invariants, methods have pre/post specs Assertion language: permissions, rich functional specs user-defined predicates (implemented or abstract) mathematical (heap-dependent) pure functions Very simple type system four basic types: Int, Bool, Perm, Ref (all references) sequence and set types: Seq[T], Set[T] (+ operations) Domains allow user to specify custom types via extra domain functions and quantified axioms e.g. tuples, maps, arrays…

Demo (encoding RSL) field val : Int // integer pointer value predicate R(x: Ref) predicate W(x: Ref) field alreadyRead : Set[Int] // for updating invariant // x.store(i,release) define RELEASE(i,x) { if(i!=0) { exhale acc(a.val) && a.val == 7 } method unknownInt() returns (x:Int) // t := x.load(acq) define ACQUIRE(t,x) { t := unknownInt() if(t==0 || t in x.alreadyRead) { // do nothing } else { inhale acc(a.val) && a.val == 7 // a.val pointsto 7 x.alreadyRead := x.alreadyRead union Set(t) define leftPre (acc(a.val) && a.val == 0 && acc(W(x))) define leftPost true define rightPre acc(R(x)) && acc(x.alreadyRead) && x.alreadyRead == Set[Int]() define rightPost true method outerScope() { var a: Ref var x: Ref x := new(); // atomic RELEASE(0,x); inhale acc(R(x)) && acc(W(x)) && acc(x.alreadyRead) && x.alreadyRead == Set[Int]() a := new(); // non-atomic inhale acc(a.val) a.val := 0 // fork both threads exhale leftPre exhale rightPre // join both threads inhale leftPost inhale rightPost method leftThread(a:Ref, x:Ref) requires leftPre ensures leftPost { a.val := 7 assert acc(W(x)) RELEASE(1,x) method rightThread(a:Ref, x:Ref) requires rightPre ensures rightPost var t : Int assert acc(R(x)) ACQUIRE(t,x) if (t != 0) { assert a.val == 7

Some Viper Applications Python ….. Java (VerCors) Chalice OpenCL (VerCors) Viper Tools released 1.5 years ago open-source, publicly available in use both at ETH and outside Chalice: re-implementation concurrency verification Scala (small fragment) Finite blocking verification VerCors (ERC) project Marieke Huisman (UTwente) Java, GPU code, kernel code SCION router code (Python) Adrian Perrig (ETH Zurich) (coming soon) JavaScript (Philippa Gardner) Fine-grained concurrency logics [Your tool name here? ]

Conclusion: Deductive Verification Tools while(i>0) { i--; }  …………  …………  ………… spec Provide powerful reasoning abstractions for direct users, but also for other tool developers to plug into Divide a concurrency verification task between: expressing appropriate specifications per program encoding (in a tool) of a concurrency reasoning technique leveraging intermediate tools and reasoning abstractions ultimately exploiting SMT solvers (+ other automatic tools?)