Lecture 13 Proof Carrying Code CS 655 Programming

  • Slides: 22
Download presentation
Lecture 13: Proof. Carrying Code CS 655: Programming Languages David Evans University of Virginia

Lecture 13: Proof. Carrying Code CS 655: Programming Languages David Evans University of Virginia CS 655 http: //www. cs. virginia. edu/~evans Computer Science

Menu • Challenge Question Solution (C++ overriding/overloading) • Proof-Carrying Code • My INFOSEC Malicious

Menu • Challenge Question Solution (C++ overriding/overloading) • Proof-Carrying Code • My INFOSEC Malicious Code Talk 2/20/2021 University of Virginia CS 655 2

Subject: Re: C++: overriding problems! Date: Sat, 4 Mar 2000 20: 19: 34 -0500

Subject: Re: C++: overriding problems! Date: Sat, 4 Mar 2000 20: 19: 34 -0500 (EST) From: Bjarne Stroustrup <bs@research. att. com> Reply-To: Bjarne Stroustrup <bs@research. att. com> To: avneesh@cs. virginia. edu > Delivered-To: bs@research. att. com > Date: Fri, 03 Mar 2000 18: 09: 53 -0500 > From: Avneesh Saxena <avneesh@cs. virginia. edu> > X-Accept-Language: en > MIME-Version: 1. 0 > To: bs@research. att. com > Subject: C++: overriding problems! > Content-Transfer-Encoding: 7 bit > > Sir, > I am Avneesh, a graduate student in the CS Dept, Univ of Virginia. I am currently taking a course on Programming languages in which we are doing a detailed study of subclassing mechanisms in computer languages. I have learned C++ from your book "The C++ Pgm'ing Language" which is written in a very clear and concise manner. Especially, the concepts are made clear and ambiguties about language features have been discussed and resolved in an appreciable manner. > However, I have run in a problem while trying to figure out what this code would do: [Unexpected results are noted as comments] 2/20/2021 University of Virginia CS 655 3

> > #include<stdio. h> > > class A { > public: > void other()

> > #include<stdio. h> > > class A { > public: > void other() { printf("is an empty func in An"); }; > virtual void other(class A *a) { printf("In An"); } > }; //End class > > class B: public A { > public: > void other(class B *b) { printf("In Bn"); } > }; //End class > > class C: public A { > public: > void other(class C *c) { printf("In Cn"); } > }; //End class Your problem is that you think that the two other() function overloads. They don't: functions in different scope do not overload, so when you look at scope C: : other(). If you want overloading you'll have to explicitly do so in C. One simple way of doing so is to say: using B: : other; in C, but that's a relatively new feature. 2/20/2021 University of Virginia CS 655 4

> void main(void) { > A a; B b; C c; > A *a.

> void main(void) { > A a; B b; C c; > A *a. Ptr = &a; > B *b. Ptr = &b; > C *c. Ptr = &c; > > a. Ptr = b. Ptr; > a. Ptr->other(b. Ptr); //prints "in A", whereas we expect it to print > "In B" > //b. Ptr->other(); //Gives an error saying can't find the function > > }//End main > I have tried to run this code both through GCC v 2. 8. 1 and MS-VC++, which give the same results. It appears that while we would accept other() to be accessible through the derived classes, the compiler doesn't find it. I think you mean "expect", but you expect wrongly. > The second (more serious)problem is when other(b. Ptr) is called, we expect it to execute the function which has been defined in class B as it overrides the function defines in class A as the type of the actual argument matches this more closely; however, it executes the base classes function (circumvents polymorphism!). I tried to check if this behavior was consistent with the language definition but I failed to find anything which would clarify things. So, I am left wondering whether this is a case of the compiler not understanding the language and doing something wrong or is it what the language desires? The compilers are wrong I suggest a re-read of the sections about deriving classes in your textbook. > I hope you will be able to clarify things for me, > Thanks, > Avs 2/20/2021 University of Virginia CS 655 5

PCC: Basic Idea • Creating a proof is hard – Have to make up

PCC: Basic Idea • Creating a proof is hard – Have to make up invariants, etc. • Checking a proof is easy – Simple mechanical application of rules • Guarantee properties of untrustworthy code by checking a proof provided by code producer 2/20/2021 University of Virginia CS 655 6

Proof-Carrying Code Certifying Compiler Program Code Producer Code Consumer Ok Native Code Proof Checker

Proof-Carrying Code Certifying Compiler Program Code Producer Code Consumer Ok Native Code Proof Checker Policy CPU 2/20/2021 University of Virginia CS 655 7

Tamper with Code Certifying Compiler Program Native Code Producer Proof Wily Hacker Code Consumer

Tamper with Code Certifying Compiler Program Native Code Producer Proof Wily Hacker Code Consumer Tampered Code No! Proof Checker CPU 2/20/2021 University of Virginia CS 655 8

Tamper with Both Certifying Compiler Program Native Code Proof Code Producer Wily P. Hacker

Tamper with Both Certifying Compiler Program Native Code Proof Code Producer Wily P. Hacker Code Consumer But it means the desired property still holds! Tampered Code Ok No! Tampered Proof Checker CPU 2/20/2021 University of Virginia CS 655 9

What must the proof prove? Safety Policy VCGen Safety Predicate Program • Depends on

What must the proof prove? Safety Policy VCGen Safety Predicate Program • Depends on the policy • Code consumer must run VCGen (can’t trust proof unless it proves safety predicate) • VCGen can be developed from an operational semantics (like you did in PS 2) 2/20/2021 University of Virginia CS 655 10

How many PCC systems in active use? • • • 2 1000 1 Million

How many PCC systems in active use? • • • 2 1000 1 Million 10 Million > 20 Million 2/20/2021 Java byte code verifier is a limited implementation of PCC: • Bytecodes include extra information on typing, stack use, etc. • Bytecode verifier checks it to enforce low-level code safety properties Peter Lee claims most linkers are instances of PCC also. University of Virginia CS 655 11

Umni. VML 2 Program: : = Type. Hint* Statement* Type. Hint: : = TYPE

Umni. VML 2 Program: : = Type. Hint* Statement* Type. Hint: : = TYPE Memory. Location Type: : = INTEGER | REF Type Statement: : = STORE Expression_m Expression_v Expression_m must have type ref (typeof Expression_v). | READ Expression must have type ref (integer). | WHILE Expression_l <= Expression_r Expression_l and Expression_r must have type integer. | ENDWHILE | HALT | CHECKTYPE Expression Type Generates a run-time error if type of Expression is not Type. Expression: : = ADD Expression_1 Expression_2 Expression_1 and Expression_2 must have type integer. | ADDP Expression_1 Expression_2 Expression_1 must have type ref(T). Expression_2 must have type integer. | DEREF Expression 2/20/2021 Expression must have type ref (T). University of Virginia CS 655 12

An Umni. VML 2 Program [T 0] TYPE M 0 INT [T 1] TYPE

An Umni. VML 2 Program [T 0] TYPE M 0 INT [T 1] TYPE M 1 REF INT [T 2] TYPE M 100 -M 200 INT % abbrev for 201 decls [0] STORE M 0 0 [1] STORE M 100 [2] WHILE DEREF M 0 <= 99 [3] CHECKTYPE DEREF M 1 REF INT [4] READ DEREF M 1 [5] STORE M 1 ADDP DEREF M 1 1 [6] STORE M 0 ADD DEREF M 0 1 [7] ENDWHILE [8] HALT 2/20/2021 University of Virginia CS 655 13

VCGen for Umni. VML 2 VCGen (PC) = if Inst[PC] = STORE Expression_m Expression_v

VCGen for Umni. VML 2 VCGen (PC) = if Inst[PC] = STORE Expression_m Expression_v typeof (Expression_m) = ref (typeof (Expression_v)) & VCGen. E (Expression_m) & VCGen. E (Expression_v) & VCGen (PC + 1) if Inst[PC] = WHILE Expression_l <= Expression_r typeof (Expression_l) = integer & typeof (Expression_r) = integer & VCGen. E (Expression_l) & VCGen. E (Expression_r) & VCGen (PC + 1) & VCGen (<pc of next ENDWHILE>) if INST[PC] = READ Expression typeof (Expression) = ref (integer) & VCGen. E (Expression) & VCGen (PC + 1) if INST[PC] = CHECKTYPE Expression Type VCGen (PC + 1) can assume typeof (Expression) = Type if INST[PC] = ENDWHILE VCGen (PC + 1) if INST[PC] = HALT true 2/20/2021 University of Virginia CS 655 14

VCGen. E (E) = if E = ADD Expression_1 Expression_2 typeof (Expression_1) = integer

VCGen. E (E) = if E = ADD Expression_1 Expression_2 typeof (Expression_1) = integer & typeof (Expression_2) = integer & VCGen. E (Expression_1) & VCGen. E (Expression_2) if E = ADDP Expression_1 Expression_2 typeof (Expression_1) = ref (T) & typeof (Expression_2) = integer & VCGen. E (Expression_1) & VCGen. E (Expression_2) if E = DEREF Expression typeof (Expression) = ref (T) & VCGen. E (Expression) if E = Int. Literal true if E = Memory. Location true 2/20/2021 University of Virginia CS 655 15

VCGen for Program [T 0] TYPE M 0 INT [T 1] TYPE M 1

VCGen for Program [T 0] TYPE M 0 INT [T 1] TYPE M 1 REF INT [T 2] TYPE M 100 -M 200 INT % abbrev for 201 decls Project Group 1 [0] STORE M 0 0 [1] STORE M 100 Group 2 [2] WHILE DEREF M 0 <= 99 Group 3 [3] CHECKTYPE DEREF M 1 REF INT [4] READ DEREF M 1 Group 4 Group 5 [5] STORE M 1 ADDP DEREF M 1 1 [6] STORE M 0 ADD DEREF M 0 1 [7] ENDWHILE Group 6 [8] HALT 2/20/2021 University of Virginia CS 655 16

Constructing a Proof A = type environment = [ M 0: ref (integer), M

Constructing a Proof A = type environment = [ M 0: ref (integer), M 1: ref (integer)), M 100 -M 200: ref (integer) ] Axioms are typing judgments (your PS 2 solution) We need to show: A proves VCGen (0) Type bindings given by CHECKTYPE Expression Type are true until STORE Expression_x Expression or READ Expression_x where typeof (Expression_x) = Type. 2/20/2021 University of Virginia CS 655 17

So Far • About as easy to generate these proofs as to check them,

So Far • About as easy to generate these proofs as to check them, so no need to pass proof around with code. • Except: the type hints are really a proof! • CHECKTYPE is expensive – optimizing compiler should be able to remove it for this program 2/20/2021 University of Virginia CS 655 18

An Umni. VML 2 Program [T 0] TYPE M 0 INT [T 1] TYPE

An Umni. VML 2 Program [T 0] TYPE M 0 INT [T 1] TYPE M 1 REF INT [T 2] TYPE M 100 -M 199 INT % abbrev for 200 decls [0] STORE M 0 0 [1] STORE M 100 [2] WHILE DEREF M 0 <= 99 Need a loop invariant [3] READ DEREF M 1 [4] STORE M 1 ADDP M 1 1 [5] STORE M 0 ADD M 0 1 [6] ENDWHILE [7] HALT 2/20/2021 University of Virginia CS 655 19

Requirements for Invariant • Strong enough to prove: Inv & Pred VCGen ([3] READ

Requirements for Invariant • Strong enough to prove: Inv & Pred VCGen ([3] READ DEREF M 1) Inv & (DEREF M 0 <= 99) typeof (DEREF M 1) = ref (integer) • Weak enough to prove: Type. Hints + [0] STORE M 0 0 + [1] STORE M 100 Inv • Weak and strong enough to prove WHILE loop axioms Inv & (DEREF M 0 <= 99) { [3] READ DEREF M 1 [4] STORE M 1 ADDP M 1 1 [5] STORE M 0 ADD M 0 1 } Inv 2/20/2021 University of Virginia CS 655 20

Loop Invariant Inv = DEREF (DEREF M 1) = 100 + DEREF M 0

Loop Invariant Inv = DEREF (DEREF M 1) = 100 + DEREF M 0 & DEREF M 0 >= 0 This is the “proof” attached to the code. Once you have it, checking is easy! 2/20/2021 University of Virginia CS 655 21

PCC Summary • Code producer provides a checkable proof of desired property • Code

PCC Summary • Code producer provides a checkable proof of desired property • Code consumer verifies the proof – Can use invariants, type hints, etc. but must not assume they are true – Help direct the checker to construct a proof quickly • Enables optimizations not possible without proof • Enables guarantees not possible without proof (lack of run-time errors) 2/20/2021 University of Virginia CS 655 22