330 likes | 424 Views
Under the Hood of the Open Verifier. Bor-Yuh Evan Chang, Adam Chlipala, Kun Gao, George Necula, and Robert Schneck October 21, 2003 OSQ Group Meeting. OV. PCC. FPCC. Less Flexible. More Flexible. Issues with PCC and FPCC. Flexibility
E N D
Under the Hood of the Open Verifier Bor-Yuh Evan Chang, Adam Chlipala, Kun Gao, George Necula, and Robert Schneck October 21, 2003 OSQ Group Meeting
OV PCC FPCC Less Flexible More Flexible Issues with PCC and FPCC • Flexibility • Can the code producer use a different (or multiple) safety enforcement mechanism(s)? • e.g., various type systems, vcgen proofs
OV FPCC PCC Less Scalable More Scalable Issues with PCC and FPCC • Scalability • Can the proof obligations for the code producer be simplified?
Issues with PCC and FPCC • Amount of Trusted Code • Can the amount of trusted code in the verification infrastructure be lessened while maintaining flexibility and scalability? PCC FPCC OV More Trusted Code Less Trusted Code
An Untrusted Verifier • The code producer supplies the verifier along with the code • flexibility: code producer can provide a verifier to handle particular enforcement mechanism • scalability: specialized reasoning for the enforcement mechanism encoded in executable form • amount of trusted code: verifier extension with specialized reasoning is not trusted OpenVer • Too hard to prove correctness of the verifier • Embed the untrusted verifier as an extension in a trusted infrastructure (the Open Verifier) code verifier extension verifier extension untrusted trusted
Outline • Motivation • Architecture Overview • Simple Local Invariants • Decoder • Extension • Coverage • Complete Local Invariants • Coverage • Summary
The Open Verifier Decoder Director locinv I trusted untrusted next locinvs E Extension code • instruction at locinv I safe if P holds • next locinvs D • a proof of P • a proof that EcoversD
Definitions and Lemmas The Open Verifier Decoder Director locinv I trusted untrusted next locinvs E Extension Cool Extension code Standard Cool Verifier
The Open Verifier Decoder Director locinv I trusted untrusted next locinvs E Extension Generic Extension code Proof Extractor for Traditional PCC
rTHIS : R, rTHIS 0, rx : S 1 Rf: rx := rTHIS rx : R, rx 0 2 L2: if rx=0 jump L9 rx : R, rx 0 3 L3: load rt from rx + 4 rt : vm(rx,4), rx : R, rx 0 4 L4: rTHIS := rx rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 5 L5: rRA := L7 rRA = L7, rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 6 L6: ijump rt rRV : S 7 L7: rx := rRV rx : S 8 L8: jump L2 9 L9: ijump rRA 20 Snext: … 30 Rnext: … An Example class S { S next() { … }; } class R extends S { S next() { … } void f(S x) { x = this; while (x != null) { x = x.next(); } } }
Local Invariants (Locinvs) - Part 1 • Language of discoursein the Open Verifier • Should be • simple, natural • sufficiently powerful, “complete” A predicate about the machine state at a specific instruction
rTHIS : R, rTHIS 0, rx : S 1 Rf: rx := rTHIS 2 L2: if rx=0 jump L9 3 L3: load rt from rx + 4 4 L4: rTHIS := rx 5 L5: rRA := L7 6 L6: ijump rt 7 L7: rx := rRV 8 L8: jump L2 9 L9: ijump rRA Local Invariants - Part 1 • Informal: At rPC = 1, the memory is laid out according to the Cool specification, rTHIS has type R, rTHIS is non-null, and rx has type S. • (More) Formal: rPC = 1 Æ (cinv rM) ; mem ok Æ rTHIS : R Æ rTHIS 0 Æ rx : S
1 Rf: rx := rTHIS 2 L2: if rx=0 jump L9 Decoder • Encodes the semantics of machine instructions and the safety policy • Essentially, a strongest-postcondition generator decoder(I) = (P,D) I: rPC = 1 Æ (cinv rM) Æ rTHIS : R Æ rTHIS 0 Æ rx : S P: True D: [9tx. rPC = 2Ærx = rTHISÆ (cinv rM) Æ rTHIS : R Æ rTHIS 0 Ætx : S]
Local Invariants - Part 2 • Existentially quantified predicates parameterized by the machine state and structured into • first-order assumptions A • Machine state specifies the values of the PC, the registers, and the memory • left implicit in the examples
Extension • Required to prove: • Local safety condition (I )P) • Either trivial or some address is valid • Type-based extensions use the soundness of the type system • Coverage (EcoversD)
Coverage • (EcoversD) means roughly where safe I means “if locinv I is satisfied, then safe progress can be made” • but it is sufficient to show
Coverage • Covering a single D = 9xD. (AD xD) • or it is sufficient to show for some E = 9xE.(AE xE) 2E
Coverage • Typically, the extension makes minor modifications to the locinv produced by the decoder. • e.g., to forget about some detailed information not necessary for demonstrating safety • Can implement proof of coverage more efficiently by considering kinds of changes • e.g., using the decoder’s locinv or simply dropping assumptions from the decoder’s locinv requires no coverage proof.
Coverage - Add Assumptions 1 Rf: rx := rTHIS I: rPC = 1 Æ (cinv rM) Æ rTHIS : R Æ rTHIS 0 Æ rx : S P: True D: [9tx. rPC = 2 Æ rx = rTHISÆ (cinv rM) Æ rTHIS : R Æ rTHIS 0 Æ tx : S] E: [rPC = 2 Æ (cinv rM) Ærx : R Æ rx 0] (EcoversD) requires 8xD. (AD xD) )rx : R Æ rx 0
(EcoversD) rTHIS : R, rTHIS 0, rx : S 1 Rf: rx := rTHIS rx : R, rx 0 2 L2: if rx=0 jump L9 rx : R, rx 0 3 L3: load rt from rx + 4 rt : vm(rx,4), rx : R, rx 0 4 L4: rTHIS := rx rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 5 L5: rRA := L7 rRA = L7, rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 6 L6: ijump rt rRV : S 7 L7: rx := rRV rx : S 8 L8: jump L2 9 L9: ijump rRA rx : S ) rx : R Æ rx 0 Coverage - Scanned Locinv (Loops) 1 L8: jump L2 I: rPC = 8 Æ (cinv rM) Æ rx : S P: True D: [rPC = L2Æ (cinv rM) Ærx : S] E: [rPC = L2Æ (cinv rM) Ærx : R Æ rx 0]
(EcoversD) rTHIS : R, rTHIS 0, rx : S 1 Rf: rx := rTHIS rx : R, rx 0 2 L2: if rx=0 jump L9 rx : R, rx 0 3 L3: load rt from rx + 4 rt : vm(rx,4), rx : R, rx 0 4 L4: rTHIS := rx rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 5 L5: rRA := L7 rRA = L7, rTHIS = rx, rt : vm(rx,4), rx : R, rx 0 6 L6: ijump rt rRV : S 7 L7: rx := rRV rx : S 8 L8: jump L2 9 L9: ijump rRA rx : S ) rx : R Æ rx 0 Coverage - Scanned Locinv (Loops) 1 L8: jump L2 I: rPC = 8 Æ (cinv rM) Æ rx : S P: True D: [rPC = L2Æ (cinv rM) Ærx : S] E: [rPC = L2Æ (cinv rM) Ærx : S]
rTHIS : R, rTHIS 0, rx : S 1 Rf: rx := rTHIS rx : S 2 L2: if rx=0 jump L9 rx : S, rx 0 3 L3: load rt from rx + 4 rt : vm(rx,4), rx : S, rx 0 4 L4: rTHIS := rx rTHIS = rx, rt : vm(rx,4), rx : S, rx 0 5 L5: rRA := L7 rRA = L7, rTHIS = rx, rt : vm(rx,4), rx : S, rx 0 6 L6: ijump rt rRV : S 7 L7: rx := rRV rx : S 8 L8: jump L2 9 L9: ijump rRA Coverage - Scanned Locinv (Loops) 1 L8: jump L2 I: rPC = 8 Æ (cinv rM) Æ rx : S P: True D: [rPC = L2Æ (cinv rM) Ærx : S] E: [rPC = L2Æ (cinv rM) Ærx : S] (from before) • Coverage is trivially satisfied here • Do not know the incremental changes
Outline • Motivation • Architecture Overview • Simple Local Invariants • Decoder • Extension • Coverage • Complete Local Invariants • Coverage • Summary
Indirect Jumps • Indirect jumps are more difficult to handle but necessary • function return, exceptions • Within the context of a particular locinv, need to state a code address is “safe to jump to” (under certain conditions) • e.g., it is “safe to jump to” the address contained in rRA.
Local Invariants - Part 3 “rPC = 9, rSAVE = 1, rRA = 27, and it is safe to jump to rPC = rRA as long as rSAVE has the same value as now.” . (rPC) = 9 Æ (rSAVE) = 1 Æ safe (’. (rPC’) = (rRA) Æ (rSAVE’) = (rSAVE))
Local Invariants - Part 3 • Existentially quantified predicates parameterized by the machine state and structured into • first-order assumptions A • progress continuationsC • a list of locinvs that are “safe to continue to” • Not a general higher-order predicate but one structured into first-order pieces.
Local Invariants - Part 3 • Fixing the machine state, a locinv I can be structured into a tuple as follows: I = 9xI.hPCI, RI, AI, CIi • PCI is an expression in terms of xI (usually, constant) • RI is a mapping from register names to expressions • AI is a first-order formula (assumptions) • CI is a list of locinvs (progress continuations)
Local Invariants - Part 3 “rPC = 9, rSAVE = 1, rRA = 27, and it is safe to jump to rPC = rRA as long as rSAVE has the same value as now.” I = . (rPC) = 9 Æ (rSAVE) = 1 Æ safe (’. (rPC’) = (rRA) Æ (rSAVE’) = (rSAVE)) I = 9xSAVE,xRA.hPCI = 9, RI = {SAVE xSAVE, RA xRA, …}, AI = (xSAVE = 1), CI = [ hPCC1 = xRA, RC1 = {SAVE xSAVE, …}, AC1 = True, CC1 = [ ]i ]i
Coverage with Progress Continuations • (EcoversD) - a single locinv means • it is sufficient to show for some E 2E[CD
Function Return 9 L9: ijump rRA I: 9xRA.hPCI = 9, RI = {RA xRA, …}, AI = True, CI = [hPCC1 = xRA,RC1 = {…},AC1 = True,CC1 = [ ]i]i P: True D: [9xRA.hPCI = xRA, RI = {RA xRA, …}, AI = True, CI = [hPCC1 = xRA,RC1 = {…},AC1 = True,CC1 = [ ]i]i] E: [ ] • In this case, D contains its own “covering” locinv C1.
Summary • Untrusted verifier extensions allows the code producer • flexibility to use various safety enforcement mechanisms • to simplify proof generation by incorporating specialized reasoning in executable form • Building extensions is simplified by • structuring invariants into first-order pieces • requiring only first-order proofs (specialized method of proving covers)
Issues • Are locinvs too restrictive? • Can proving coverage be simplified (and made more efficient)? • by specializing to common cases?