Program Verification (6EC version only)

Similar documents
JML tool-supported specification for Java Erik Poll Radboud University Nijmegen

Introduction to JML David Cok, Joe Kiniry, and Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

ESC/Java2 extended static checking for Java Erik Poll Radboud University Nijmegen

Assertions & Design-by-Contract using JML Erik Poll University of Nijmegen

Programming with Contracts. Juan Pablo Galeotti, Alessandra Gorla Saarland University, Germany

ESC/Java extended static checking for Java Erik Poll, Joe Kiniry, David Cok University of Nijmegen; Eastman Kodak Company

ESC/Java2 Use and Features

ESC/Java2 Use and Features

Static program checking and verification

JML. Outline. Métodos Formais em Engenharia de Software. MI, Braga these slides were prepared by adopting/adapting teaching material

Lecture 10 Design by Contract

Advanced JML. and more tips and pitfalls. David Cok, Joe Kiniry, and Erik Poll

Overview The Java Modeling Language (Part 1) Related Work

ESC/Java2 Warnings David Cok, Joe Kiniry, and Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

The Java Modeling Language (Part 1)

Java Modeling Language (JML)

CS 161 Computer Security

Formale Entwicklung objektorientierter Software

Java Modelling Language (JML) References

Software Security: Vulnerability Analysis

A Java Reference Model of Transacted Memory for Smart Cards

Advanced JML Erik Poll Radboud University Nijmegen

The Java Modeling Language JML

Specification tips and pitfalls

Verification Condition Generation

ESC/Java2 Use and Features David Cok, Joe Kiniry, Erik Poll Eastman Kodak Company, University College Dublin, and Radboud University Nijmegen

OOP Design by Contract. Carsten Schuermann Kasper Østerbye IT University Copenhagen

Formal Specification and Verification

JML. Java Modeling Language

ESC/Java2 vs. JMLForge. Juan Pablo Galeotti, Alessandra Gorla, Andreas Rau Saarland University, Germany

Advances in Programming Languages

Checking Program Properties with ESC/Java

Hoare Logic: Proving Programs Correct

Advances in Programming Languages

Formal Methods for Java

objects

Specification of a transacted memory for smart cards in Java and JML

Verifying JML specifications with model fields

Runtime Checking for Program Verification Systems

Proof Carrying Code(PCC)

FreePascal changes: user documentation

Formal Specification and Verification

Analysis of Software Artifacts

Assertions, pre/postconditions

Advances in Programming Languages

Deductive Verification in Frama-C and SPARK2014: Past, Present and Future

Formal Systems II: Applications

Contents. Program 1. Java s Integral Types in PVS (p.4 of 37)

Lecture Notes: Hoare Logic

Assertions. Assertions - Example

Formal Methods for Java

UC Santa Barbara. CS189A - Capstone. Christopher Kruegel Department of Computer Science UC Santa Barbara

Lecture 1 Contracts. 1 A Mysterious Program : Principles of Imperative Computation (Spring 2018) Frank Pfenning

Lecture 3 Notes Arrays

Testing, Debugging, and Verification

JML Class Specifications The Java Modeling Language (Part 2) A Java Class

Testing, Debugging, Program Verification

Why. an intermediate language for deductive program verification

Lecture Notes on Memory Layout

The Java Modeling Language (Part 2)

Spark verification features

Counterexample Guided Abstraction Refinement in Blast

Verification Conditions. Juan Pablo Galeotti, Alessandra Gorla, Andreas Rau Saarland University, Germany

ESC/Java 2. Checker for Java 2. Extended. Static. B y K ats man Andrey S oftware E ngineering S em inar

Fundamentals of Software Engineering

SPARKSkein A Formal and Fast Reference Implementation of Skein

Lecture 1 Contracts : Principles of Imperative Computation (Fall 2018) Frank Pfenning

Recap. Juan Pablo Galeotti,Alessandra Gorla, Software Engineering Chair Computer Science Saarland University, Germany

BOOGIE. Presentation by Itsik Hefez A MODULAR REUSABLE VERIFIER FOR OBJECT-ORIENTED PROGRAMS MICROSOFT RESEARCH

Motivation. Correct and maintainable software Cost effective software production Implicit assumptions easily broken

Reachability Analysis for Annotated Code

Java Modelling Language (JML) References

EXAMINATIONS 2009 MID-TERM TEST. COMP 202 / SWEN 202 Formal Methods of Computer Science / Formal Foundations of Software Engineering WITH ANSWERS

JPred-P 2. Josh Choi, Michael Welch {joshchoi,

Exercise 3 Subtyping and Behavioral Subtyping October 13, 2017

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

Symbolic Execution and Verification Conditions. Review of Verification Conditions. Survey from Homework 4. Time spent: 7.1 hrs (mean), 6 hrs (median)

Local Verification of Global Invariants in

Overview. Verification with Functions and Pointers. IMP with assertions and assumptions. Proof rules for Assert and Assume. IMP+: IMP with functions

Announcements. Specifications. Outline. Specifications. HW1 is due Thursday at 1:59:59 pm

Design by Contract and JML: concepts and tools

FAKULTÄT FÜR INFORMATIK

Program Correctness and Efficiency. Chapter 2

Cover Page. The handle holds various files of this Leiden University dissertation

'Safe' programming languages

Memory Safety (cont d) Software Security

Programming Languages Third Edition

An Extensible Programming Language for Verified Systems Software. Adam Chlipala MIT CSAIL WG 2.16 meeting, 2012

The JML Tool. Faculty of Engineering Pontificia Universidad Javeriana. The JML Tool p.1/23

6. Hoare Logic and Weakest Preconditions

Extended Static Checking for Java

Hybrid Verification in SPARK 2014: Combining Formal Methods with Testing

Semantic Analysis. CSE 307 Principles of Programming Languages Stony Brook University

JML and ESC/Java2 Homework Exercises

Object Ownership in Program Verification

Reasoning about programs

Last time. Reasoning about programs. Coming up. Project Final Presentations. This Thursday, Nov 30: 4 th in-class exercise

Guidelines for Writing C Code

Automatic Generation of Program Specifications

Specification and Verification of Garbage Collector by Java Modeling Language

Transcription:

Program Verification (6EC version only) Erik Poll Digital Security Radboud University Nijmegen

Overview Program Verification using Verification Condition Generators JML a formal specification language for Java Used for the program verification exercise 2

Program verification Formally proving (in the mathematical/logical sense) that a program satisfies some property eg that it does not crash, always terminates, never terminates, meets some functional specification, meets some security requirement, etc for all possible executions: ie all possible inputs and all possible scheduling of parallel threads. NB in industry, the term verification is used for testing but testing provides only weaker guarantees because testing will only try some executions except in rare case where you can do exhaustive testing Formal verification provides the highest level of assurance that code is correct & secure provided you can formally verify what it means for the code to be secure 3

What do we need for program verification? 1. a formal semantics of the programming language 2. a specification language to express properties 3. a logic to reason about programs and specifications aka a program logic 4. a verification tool to support all this These topics are investigation in the field of field of formal methods 4

For the program... x[4] = false;... What to verify? Example we might want to verify that here x is not null and 4 is within the array bounds (and that x is a Boolean array) Proving absence of runtime exceptions (or, in an unsafe language like C, memory-safety, or more generally, the absence of undefined behavior) is a great bottom-line specification to start verification! Typing is a simple form of program verification, for a limited and relatively weak class of properties, eg x is a byte array A type checker can be regarded as an automated program verifier for this class of properties. 5

How to specify what we want to verify? A common way to write we want to verify is using assertions, ie properties that hold at specific program points... // assert x!= NULL && x.length > 4; x[4] = false;... Assertions written as annotations in code are also useful for testing, and for generating bug reports. For methods or procedures, we can give pre- and post-conditions 6

How to verify? Is the assertion below always true?... if (x < y) { int z; z = y; y = x; x = z;} // assert y <= x How do your verify this? You follow all paths in the control flow graph, and check that for each path the property holds using normal logical reasoning Ways to formalize this reasoning process compute verification conditions using weakest precondition calculation (or strongest postcondition ~) use symbolic execution to obtain these verification conditions 7

Complication 1 : cycles Is the assertion below always true?... int i = x-y; while (i > 0) { y++; } // assert y >= x i--; We can t follow all paths through the control flow graph, as the graph contains a cycle. We need a loop invariant. 8

Complication 1 : cycles Is the assertion below always true?... int i = x-y; // so y+i == x while (i > 0) { y++; // now y+i == x+1 i--; // now y+i == x } // now i <= 0 (because we exited the while loop) // and y+i == x (because it is a loop invariant) // and therefore y >= x Once we realise that y+i == x is a loop invariant, we can split the graph in a finite number of segments, and check that each segments meets the specification 9

Complication 2 : modularity & the heap Programming languages offer procedures or methods for modularity. This complicates reasoning.... x = 5; p(); // assert x == 5 Is the assertion always true? 10

Complication 2 : modularity & the heap If x is on the stack, the assertion is always true proc m() { int x; x = 5; p(); // assert x == 5 } because x is out of scope for p() assuming that we are in a memory-safe language: if p contains buffer overflows, pointer arithmetic, all bets are off! 11

Complication 2 : modularity & the heap If x is on the heap, things become tricky even in a safe programming language! In Java, will the assertion below always hold? x = 5; o.p(); // assert x == 5 12

Complication 2 : modularity & the heap class A { static int x = 12; // ie a class field public void m() { }... x = 5; o.p(); // assert x == 5 Is the assertion below always true? No, because o.p()might change A.x 13

Complication 2 : modularity & the heap class A { int x = 12; public void m() { }... x = 5; o.p(); // assert x == 5 Assertion is not guaranteed to hold, because o might be aliased to this and o.p()could change x o might have a reference to this and then change x, via the reference if x x is not private, or by invoking a method... 14

... x = 5; // assert x == 5 Complication 3 Is the assertion always true? 15

Complication 3: concurrency & the heap... x = 5; // assert x == 5 Is the assertion always true? No, not if there is another thread running that may also be accessing x The problem, and possible solutions, are very similar to the problem of modular reasoning about procedures/methods. Solutions include separation logic, implicit dynamic frames, or ownership Newer programming languages such as Rust might be better suited for reasoning about concurrency 16

Program Verification using Verification Condition Generation 17

Program Verification using VCGen One of the standard approaches for program verification: using Verification Condition Generator (VCGen): 1. Program is annotated with properties (the specification) 2. Verification Condition Generator produces a set of logical properties, the so-called verification conditions 3. If these verification conditions are true, the annotations are correct ie the program satisfies the specification annotated program VCgen verification conditions (automated) theorem prover OK / Not OK 18

Example verification using VCGen //@ requires true; //@ ensures \result > 5; public int example(int j) { } if (j < 8) { } int i = 2; while (j < 6*i){ } j = j + i; return j; These annotations give a pre- and postcondition that form the specification: on any input, this method will return a result greater than 5 is this specification always met? how do you know this? could an automated tool reproduce your reasoning? 19

Verification using VCGen (i) program as graph //@ ensures \result > 5; public int example(int j)!(j<8) { if (j < 8) { int i = 2; while (j < 6*i){ j = j + i; } }!(j<6*i) return j; } return j start if(j<8) j<8 int i=2 while(j<6*i) j<6*i j=j+i end 20

Verification using VCGen (ii) add assertions Pre: true start //@ ensures \result > 5; public int example(int j)!(j<8) { if (j < 8) { int i = 2; /*@ loop_invariant i==2; @*/ while (j < 6*i){ if(j<8) j<8 int i=2 Loop inv: i==2 j = j + i;!(j<6*i) while(j<6*i) } } return j j<6*i } return j; j=j+i Post: \result > 5 end 21

Verification using VCGen (iii) compute VCs & check verification condition: i==2 &&!(j<6*i) ==> j>5 verification condition: i==2 && j<6*i ==> i==2 verification condition: true ==> true Compute WP: j > 5 return j Post: \result > 5 end!(j<8) Compute WP: true Loop inv: i==2!(j<6*i) Compute WP: i==2 start int i=2 j<6*i Pre: true Compute WP: true if(j<8) j<8 while(j<6*i) j=j+i 22

Verification condition generation Given a postcondition and loop invariants compute a assertion P s for every state s based on assertions P s of the states s reachable from s key idea: P s is the weakest predicate such that if it hold in state s, and the program goes to state s then P s will hold in that state s all that remains to be verified Pre P 0 the precondition specified in the program implies the assertion computed for the initial state Loop s P s each loop assertion specified in the program implies the assertion computed for that state 23

Opposite approach: forward instead of backwards Instead of working backwards from the postcondition of the final state, you can work forward from the precondition in the initial state: you then compute strongest postconditions instead of weakest preconditions This is very similar to symbolic execution of a program. 24

Tricky issues in program verification Whatever the approach, the bottlenecks in program verification remain 1. pointers / references & the heap Reasoning about data on the heap is difficult. Even in a language with automatic memory management, such as Java or C#, we still have the complication of aliasing 2. concurrency aka multi-threading 25

Examples of program verification for security Verification of Microsoft Hyper-V Hypervisor using the VCC program verifier for C [2009] the motivation to verify this is security! Info on VCC http://research.microsoft.com/en-us/projects/vcc/ Video presentation on VCC http://channel9.msdn.com/posts/peli/michal-moskal-and-the-verified-c-compiler/ Verification of sel4 microkernel in L4.verified project at NICTA http://ts.data61.csiro.au/projects/ts/l4.verified/ Fully verified TLS implementation mitls https://mitls.org 26

JML Formal specification for Java

JML Formal specification language for Java Properties can be specified in Design-By-Contract style, using pre/postconditions and object invariants NB by default, in JML invariants are object invariants, not loop invariants. Various tools to check JML specifications by eg runtime checking program verification 28

to make JML easy to use JML annotations are added as special Java comments, between /*@.. @*/ or after //@ JML specs can be in.java files, or in separate.jml files Properties specified using Java syntax, extended with some operators \old( ), \result, \forall, \exists, ==>,.. and some keywords requires, ensures, invariant,... 29

Example JML public class ChipKnip{ private int balance; //@ invariant 0 <= balance && balance < 500; //@ requires amount >= 0; //@ ensures balance <= \old(balance); //@ signals (BankException) balance == \old(balance); public debit(int amount) { if (amount > balance) { throw (new BankException("No way"));} balance = balance amount; } 30

JML basics preconditions requires postconditions ensures exceptional postconditions signals (object) invariants invariant must be established by constructors must be preserved by methods ie. assuming invariant holds in pre-state, it must hold in the post-state 31

Exceptional postconditions: signals //@ requires. //@ ensures) //@ signals (BankException) balance == \old(balance); public debit(int amount) throws BankException { if (amount > balance) { throw (new BankException("No way"));} balance = balance amount; } But you can ignore this for the practical exercise! There we will always prove that no exceptions can be thrown. JML convention: a method may only throw exceptions that are explicitly listed in the throws clause. (Java allows implicit Runtime- excptions, eg Nullpointer- and ArrayIndexOutofBound; JML does not!) 32

non_null Lots of invariants and preconditions are about reference not being null, eg int[] a; //@ invariant a!= null; Therefore there is a shorthand /*@ non_null @*/ int[] a; But, as most references are non-null, some JML tools adopt this as default, so that only nullable fields, arguments and return types need to be annotated, eg /*@ nullable @*/ int[] b; We could also use JSR308 Java tags for this @Nullable int[] b; 33

Defaults specs and joining specs Default pre- and postconditions //@ requires true; //@ ensures true; can be omitted //@ requires P //@ requires Q means the same as //@ requires P && Q; but the former may allow tools to give more precise feedback, namely on whether P or Q is not satisfied 34

What can you do with this? Documentation/specification explicitly record detailed design decisions & document assumptions (and hence obligations!) precise, unambiguous documentation Use tools for parsed & type checked runtime assertion checking eg when testing code compile time program analysis up to full formal program verification 35

assert and loop_invariant Inside method bodies, JML allows assertions /*@ assert (\forall int i; 0<= i && i< a.length; a[i]!= null ); @*/ loop invariants /*@ loop_invariant 0<= n && n < a.length & (\forall int i; 0<= i & i < n; a[i]!= null ); @*/ 36

Program verification tools, such as ESC/Java2, KeY, Krakatoa,... can do program verification of JML-annotated Java code There is a limit to what fully automated tools, such as ESC/Java2, can verify eg. they won't be able to prove Fermat's Last theorem So far, only really feasible for small(ish) programs incl. realistic Java Card smart card applications In addition to doing the verification, which is a lot of work, a bottleneck is expressing the security property you want to verify 37

JML for security JML can be used to specify for instance 1. which if any - exceptions can be thrown incorrectly/not handling errors common source of security problems 2. security-critical invariants to be preserved even when exceptions occur 3. assumptions on input the application relies on 4. any property expressible by security automaton Simply trying to verify that a program throws no exceptions or just no Nullpointer-exceptions - will expose many (implicit) invariants and assumptions on input 38

Related work Spec# for C# by Rustan Leino & co at Microsoft Research SparkAda for Ada by Praxis High Integrity System ACSL for C used in the Frama-C toolset https://www.youtube.com/watch?v=j_xgbo5-32k Some industrial usage, but esp. for safety-critical software (notably in avionics) rather than security-critical software 39