Lectures on Proof-Carrying Code Peter Lee Carnegie Mellon University Lecture 2 (of 3) June 21-22, 2003 University of Oregon 2004 Summer School on Software.

Slides:



Advertisements
Similar presentations
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 1 Summer school on Formal Models.
Advertisements

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?
Semantics Static semantics Dynamic semantics attribute grammars
ICE1341 Programming Languages Spring 2005 Lecture #6 Lecture #6 In-Young Ko iko.AT. icu.ac.kr iko.AT. icu.ac.kr Information and Communications University.
Hoare’s Correctness Triplets Dijkstra’s Predicate Transformers
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
Types, Proofs, and Safe Mobile Code The unusual effectiveness of logic in programming language research Peter Lee Carnegie Mellon University January 22,
David Evans CS655: Programming Languages University of Virginia Computer Science Lecture 19: Minding Ps & Qs: Axiomatic.
VIDE als voortzetting van Cocktail SET Seminar 11 september 2008 Dr. ir. Michael Franssen.
Axiomatic Verification I Prepared by Stephen M. Thebaut, Ph.D. University of Florida Software Testing and Verification Lecture 17.
Copyright © 2006 Addison-Wesley. All rights reserved.1-1 ICS 410: Programming Languages Chapter 3 : Describing Syntax and Semantics Axiomatic Semantics.
ISBN Chapter 3 Describing Syntax and Semantics.
Copyright © 2006 Addison-Wesley. All rights reserved. 3.5 Dynamic Semantics Meanings of expressions, statements, and program units Static semantics – type.
Predicate Transformers
Program Proving Notes Ellen L. Walker.
1 Semantic Description of Programming languages. 2 Static versus Dynamic Semantics n Static Semantics represents legal forms of programs that cannot be.
1/22 Programs : Semantics and Verification Charngki PSWLAB Programs: Semantics and Verification Mordechai Ben-Ari Mathematical Logic for Computer.
CS 355 – Programming Languages
The Design and Implementation of a Certifying Compiler [Necula, Lee] A Certifying Compiler for Java [Necula, Lee et al] David W. Hill CSCI
Code-Carrying Proofs Aytekin Vargun Rensselaer Polytechnic Institute.
Language Specfication and Implementation - PART II: Semantics of Procedural Programming Languages Lee McCluskey Department of Computing and Mathematical.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Proof-system search ( ` ) Interpretation search ( ² ) Main search strategy DPLL Backtracking Incremental SAT Natural deduction Sequents Resolution Main.
Hoare-style program verification K. Rustan M. Leino Guest lecturer Rob DeLine’s CSE 503, Software Engineering University of Washington 26 Apr 2004.
CS 330 Programming Languages 09 / 18 / 2007 Instructor: Michael Eckmann.
Lectures on Proof-Carrying Code Peter Lee Carnegie Mellon University Lecture 1 (of 3) June 21-22, 2003 University of Oregon 2004 Summer School on Software.
From last time S1: l := new Cons p := l S2: t := new Cons *p := t p := t l p S1 l p tS2 l p S1 t S2 l t S1 p S2 l t S1 p S2 l t S1 p L2 l t S1 p S2 l t.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
CS 330 Programming Languages 09 / 16 / 2008 Instructor: Michael Eckmann.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
Software Verification Bertrand Meyer Chair of Software Engineering Lecture 2: Axiomatic semantics.
Describing Syntax and Semantics
Reading and Writing Mathematical Proofs
Proof Carrying Code Zhiwei Lin. Outline Proof-Carrying Code The Design and Implementation of a Certifying Compiler A Proof – Carrying Code Architecture.
1 Inference Rules and Proofs (Z); Program Specification and Verification Inference Rules and Proofs (Z); Program Specification and Verification.
Chapter 25 Formal Methods Formal methods Specify program using math Develop program using math Prove program matches specification using.
Proof-Carrying Code & Proof-Carrying Authentication Stuart Pickard CSCI 297 June 2, 2005.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
CS 363 Comparative Programming Languages Semantics.
Mobility, Security, and Proof-Carrying Code Peter Lee Carnegie Mellon University Lecture 2 July 11, 2001 Overview of PCC and Safety Policies Lipari School.
Muhammad Idrees Lecturer University of Lahore 1. Outline Introduction The General Problem of Describing Syntax Formal Methods of Describing Syntax Attribute.
ISBN Chapter 3 Describing Semantics.
Chapter 3 Part II Describing Syntax and Semantics.
Semantics In Text: Chapter 3.
COP4020 Programming Languages Introduction to Axiomatic Semantics Prof. Robert van Engelen.
1 / 48 Formal a Language Theory and Describing Semantics Principles of Programming Languages 4.
13 Aug 2013 Program Verification. Proofs about Programs Why make you study logic? Why make you do proofs? Because we want to prove properties of programs.
Principle of Programming Lanugages 3: Compilation of statements Statements in C Assertion Hoare logic Department of Information Science and Engineering.
SAFE KERNEL EXTENSIONS WITHOUT RUN-TIME CHECKING George C. Necula Peter Lee Carnegie Mellon U.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
Cs7100(Prasad)L18-9WP1 Axiomatic Semantics Predicate Transformers.
CSC3315 (Spring 2009)1 CSC 3315 Languages & Compilers Hamid Harroud School of Science and Engineering, Akhawayn University
C HAPTER 3 Describing Syntax and Semantics. D YNAMIC S EMANTICS Describing syntax is relatively simple There is no single widely acceptable notation or.
Mobility, Security, and Proof-Carrying Code Peter Lee Carnegie Mellon University Lecture 2 July 11, 2001 Overview of PCC and Safety Policies Lipari School.
Formal Methods in Software Engineering 1
Hoare-style program verification
Lecture 5 Floyd-Hoare Style Verification
Programming Languages and Compilers (CS 421)
Logic for Computer Security Protocols
Semantics In Text: Chapter 3.
Formal Methods in software development
Predicate Transformers
Formal Methods in software development
Program correctness Axiomatic semantics
Lecture 2: Axiomatic semantics
Programming Languages and Compilers (CS 421)
COP4020 Programming Languages
Presentation transcript:

Lectures on Proof-Carrying Code Peter Lee Carnegie Mellon University Lecture 2 (of 3) June 21-22, 2003 University of Oregon 2004 Summer School on Software Security

Some loose ends “Certified code is an old idea” see Butler Lampson’s 1974 paper: An open operating system for a single-user machine. Operating Systems Proceedings of an International Symposium, LNCS 16.

Java Grande Suite sec

Java Grande Benchmark Suite ops

Back to our case study Program AlsoInteresting while read() != 0 i := 0 while i < 100 use 1 i := i + 1

The language s ::= skip | i := e | if e then s else s | while e do s | s ; s | use e | acquire e

Defining a VCgen To define a verification-condition generator for our language, we start by defining the language of predicates P ::= b | P Æ P | A ) P | 8 i.P | e? P : P A ::= b | A Æ A b ::= true | false | e ¸ e | e = e predicates annotations boolean expressions

Weakest preconditions The VCgen we define is a simple variant of Dijkstra’s weakest precondition calculus It makes use of generalized predicates of the form: (P,e) (P,e) is true if P is true and at least e units of the resource are currently available

Hoare triples The VCgen’s job is to compute, for each statement S in the program, the Hoare triple  (P’,e’) S (P,e) which means, roughly: If (P,e) holds prior to executing S, and then S is executed and it terminates, then (P’,e’) holds afterwards

VCgen Since we will usually have the postcondition (true,0) for the last statement in the program, we can define a function vcg(S, (P,i)) ! (P’,i’) I.e., given a statement and its postcondition, generate the weakest precondition

The VCgen (easy parts) vcg(skip, (P,e))= (P,e) vcg(s 1 ;s 2, (P,e))= vcg(s 1, vcg(s 2, (P,e))) vcg(x:=e’, (P,e))= ([e’/x]P, [e’/x]e) vcg(if b then s 1 else s 2, (P,e)) = (b? P 1 :P 2, b? e 1 :e 2 ) where (P 1,e 1 ) = vcg(s 1,(P,e)) and (P 2,e 2 ) = vcg(s 2,(P,e)) vcg(use e’, (P,e))= (P Æ e’ ¸ 0, e’ + (e ¸ 0? e : 0) vcg(acquire e’, (P,e)) = (P Æ e’ ¸ 0, e-e’)

Example 1 acquire 3 use 2 (true, 0) (true Æ 2 ¸ 0, 2+0) vcg(use e’, (P,e))= (P Æ e’ ¸ 0, e’ + (e ¸ 0? e:0) vcg(acquire e’, (P,e)) = (P Æ e’ ¸ 0, e-e’) (true Æ 2 ¸ 0 Æ 3 ¸ 0, 2+0-3) Pre: (true,0) Post: (true,0) Prove: Pre ) (true,-1)

Example 2 acquire 3 use 2 use 1 (true, 0) (true Æ 1 ¸ 0, 1+0) (true Æ 1 ¸ 0 Æ 2 ¸ 0 Æ 3 ¸ 0, ) (true Æ 1 ¸ 0 Æ 2 ¸ 0, 2+1+0) vcg(use e’, (P,e))= (P Æ e’ ¸ 0, e’ + (e ¸ 0? e:0) vcg(acquire e’, (P,e)) = (P Æ e’ ¸ 0, e-e’)

Example 3 acquire 9 if (b) then use 5 else use 4 use 4 vcg(if b then s1 else s2, (P,e)) = (b? P1:P2, b? e1:e2) where (P1,e1) = vcg(s1,(P,e)) and (P2,e2) = vcg(s2,(P,e)) (true, 0) (4 ¸ 0, 4) (4 ¸ 0, 8) (5 ¸ 0, 9) (b?true:true, b?9:8) (9 ¸ 0, (b?9:8) - 9)

Example 4 acquire 8 if (b) then use 5 else use 4 use 4 vcg(if b then s1 else s2, (P,e)) = (b? P1:P2, b? e1:e2) where (P1,e1) = vcg(s1,(P,e)) and (P2,e2) = vcg(s2,(P,e)) (true, 0) (4 ¸ 0, 4) (4 ¸ 0, 8) (5 ¸ 0, 9) (b?true:true, b?9:8) (8 ¸ 0, (b?9:8) - 8)

Loops Loops cause an obvious problem for the computation of weakest preconditions acquire n i := 0 while (i<n) do { use 1 i := i + 1 }

Snipping up programs A simple loop I I I Pre I Post I Broken into segments

Loop invariants We thus require that the programmer or compiler insert invariants to cut the loops acquire n i := 0 while (i<n) do { use 1 i := i + 1 } with (i · n, n-i) An annotated loop A ::= b | A Æ A

VCgen for loops vcg(while b do s with (A I,e I ), (P,e)) = (A I Æ 8 i 1,i 2,….A I ) b ?P’ Æ e I ¸ e’, : P Æ e i ¸ e, e I ) where (P’,e’) = vcg(s,(A I,e I )) and i 1,i 2,… are the variables modified in s

Example 5 acquire n; i := 0; while (i<n) do { use 1; i := i + 1; } with (i · n,n-i); (true, 0) (i · n, n-i) (i+1 · n, n-(i+1)) (i+1 · n Æ 1 ¸ 0, n-i) (i · n Æ 8 i.i · n ) cond(i<n,i+1 · n Æ n-i ¸ n-i, n-i ¸ n-i) n-i) (0 · n Æ 8 i. …, n-0) (… \and n ¸ 0, n-n)

Our easy case Program Static acquire i := 0 while i < use 1 i := i + 1 with (i · 10000, i) Typical loop invariant for “standard for loops”

Our hopeless case Program Dynamic while read() != 0 acquire 1 use 1 with (true, 0) Typical loop invariant for “Java-style checking”

Our interesting case Program Interesting N := read() acquire N i := 0 while i < N use 1 i := i + 1 with (i · N, N-i)

Also interesting Program AlsoInteresting while read() != 0 acquire 100 i := 0 while i < 100 use 1 i := i + 1 with (i · 100, 100-i)

Annotating programs How are these annotations to be inserted? The programmer could do it Or: A compiler could start with code that has every use immediately preceded by an acquire We then have a code-motion optimization problem to solve

VCGen’s Complexity Some complications: If dealing with machine code, then VCGen must parse machine code. Maintaining the assumptions and current context in a memory- efficient manner is not easy. Note that Sun’s kVM does verification in a single pass and only 8KB RAM!

VC Explosion a == b a == c f(a,c) a := xc := x a := yc := y a=b => (x=c => safe f (y,c)  x<>c => safe f (x,y))  a<>b => (a=x => safe f (y,x)  a<>x => safe f (a,y)) Exponential growth in size of the VC is possible.

VC Explosion a == b a == c f(a,c) a := xc := x a := yc := y INV: P(a,b,c,x) (a=b => P(x,b,c,x)  a<>b => P(a,b,x,x))  (  a’,c’. P(a’,b,c’,x) => a’=c’ => safe f (y,c’)  a’<>c’ => safe f (a’,y)) Growth can usually be controlled by careful placement of just the right “join-point” invariants.

Proving the Predicates

Proving predicates Note that left-hand side of implications is restricted to annotations vcg() respects this, as long as loop invariants are restricted to annotations P ::= b | P Æ P | A ) P | 8 i.P | e? P : P A ::= b | A Æ A b ::= true | false | e ¸ e | e = e predicates annotations boolean expressions

A simple prover We can thus use a simple prover with functionality prove(annotation,pred) ! bool where prove(A,P) is true iff A ) P i.e., A ) P holds for all values of the variables introduced by 8

A simple prover prove(A,b)= : sat(A Æ : b) prove(A,P 1 Æ P 2 )= prove(A,P 1 ) Æ prove(A,P 2 ) prove(A,b? P 1 :P 2 )= prove(A Æ b,P 1 ) Æ prove(A Æ : b,P 2 ) prove(A,A 1 ) P)= prove(A Æ A 1,P) prove(A, 8 i.P)= prove(A,[a/i]P) (a fresh)

Soundness Soundness is stated in terms of a formal operational semantics. Essentially, it states that if Pre ) vcg(program) holds, then all use e statements succeed

Logical Frameworks

Logical frameworks The Edinburgh Logical Framework (LF) is a language for specifying logics. LF is a lambda calculus with dependent types, and a powerful language for writing formal proof systems.

LF The Edinburgh Logical Framework language, or LF, provides an expressive language for proofs- as-programs. Furthermore, it use of dependent types allows, among other things, the axioms and rules of inference to be specified as well

Pfenning’s Elf true: pred. false: pred. /\: pred -> pred -> pred. \/: pred -> pred -> pred. =>: pred -> pred -> pred. all: (exp -> pred) -> pred. Several researchers have developed logic programming languages based on these principles. One of special interest, as it is based on LF, is Pfenning’s Elf language and system. This small example defines the abstract syntax of a small language of predicates

Elf example So, for example: Can be written in Elf as all([a:pred] all([b:pred] => (/\ a b) (/\ b a))) true: pred. false: pred. /\: pred -> pred -> pred. \/: pred -> pred -> pred. =>: pred -> pred -> pred. all: (exp -> pred) -> pred.

Proof rules in Elf Dependent types allow us to define the proof rules… pf: pred -> type. truei: pf true. andi: {P:pred} {Q:pred} pf P -> pf Q -> pf (/\ P Q). andel: {P:pred} {Q:pred} pf (/\ P Q) -> pf P. ander: {P:pred} {Q:pred} pf (/\ P Q) -> pf Q. impi: {P1:pred} {P2:pred} (pf P1 -> pf P2) -> pf (=> P1 P2). alli: {P1:exp -> pred} ({X:exp} pf (P1 X)) -> pf (all P1). e: exp -> pred

Proofs in Elf …which in turns allows us to have easy-to-validate proofs … (impi (/\ a b) (/\ b a) ([ab:pf(/\ a b)] (andi b a (ander a b ab) (andel a b ab))))…) : all([a:exp] all([b:exp] => (/\ a b) (/\ b a))).

LF as the internal language Explanation Code Verification condition generator Checker Proof rules Agent Host LF is the language of the blue arrows

Code producerHost

This store instruction is dangerous! Code producerHost

I am convinced it is safe to execute only if all([a:exp] (all([b:exp] (=> (/\ a b) (/\ b a))) Code producerHost A verification condition

… (impi (/\ a b) (/\ b a) ([ab:pf(/\ a b)] (andi b a (ander a b ab) (andel a b ab))))…) Code producerHost

Your proof typechecks. I believe you because I believe in logic. Code producerHost