1 / 41

An Introduction to Automated Program Verification with Permission Logics

An Introduction to Automated Program Verification with Permission Logics. Uri Juhasz , Ioannis Kassios , Peter Müller, Milos Novacek , Malte Schwerhoff , Alex Summers (and several students ). 15 th May 2015, Systems Group, ETH Zurich. Initial Example (Pseudo Java). class Cell {

rdaniell
Download Presentation

An Introduction to Automated Program Verification with Permission Logics

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. An Introduction to Automated Program Verification with Permission Logics Uri Juhasz, IoannisKassios, Peter Müller, Milos Novacek,MalteSchwerhoff, Alex Summers (and several students) 15th May 2015, Systems Group, ETH Zurich

  2. Initial Example (Pseudo Java) class Cell { int v void add(Cell c) { v = v + c.v } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assertc1.v == 3 assertc2.v == 2 } Goal: Check assertions statically Challenges: • Whole-code analysis is expensive • Dynamic dispatch (inheritance; open-world assumption)

  3. Modularity class Cell { int v void add(Cell c) { v = v + c.v } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 } ?

  4. Specifications class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) { v = v + c.v } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 }

  5. Reasoning with Specifications class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) { v = v + c.v } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 } ?

  6. An Incorrect Implementation class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) { v = v + c.v c.v = 0 } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 }  

  7. Strengthening Specifications class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) ensures c.v == old(c.v) { v = v + c.v c.v = 0 } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 } 

  8. Strengthening Specifications class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) ensures c.v == old(c.v) { v = v + c.v } } void client() { Cell c1 = new Cell() c1.v = 1 Cell c2 = new Cell() c2.v = 2 c1.add(c2) assert c1.v == 3 assertc2.v == 2 } ?

  9. Aliasing class Cell { int v void add(Cell c) requires c != nullensures v == old(v) + old(c.v) ensures c.v == old(c.v) { v = v + c.v } } voidclient() { Cellc1 = newCell() c1.v = 1 Cellc2 := newCell() c2.v = 2 c1.add(c1)// ensures c1.v == 1 + 1 // ensures c1.v == 1 assert c1.v == 3 assertc2.v == 2 }   

  10. Challenges Reason about Shared State(Including Data Races) and Control Aliasing

  11. Modular Static Verification + Shared State foo(x) bar(x)  

  12. Modular Static Verification + Shared State foo(x) bar(x)  ? 

  13. Modular Static Verification + Shared State foo(x) bar(x) ? ? ?

  14. Permissions foo(x) bar(x)  

  15. Permission Transfer foo(x) bar(x)  ? 

  16. Permission Transfer foo(x) bar(x) ? ? 

  17. Fractional Permissions foo(x) bar(x)  

  18. Splitting Fractional Permissions foo(x) bar(x)  ? 

  19. Merging Fractional Permissions foo(x) bar(x)  ? 

  20. Silver: Assertion Language Basics Accessibility predicates denote permissions Assertions may be heap-dependent Fractional permissions Conjunction sums up permissions(similar to ∗ in separation logic) Write permission is exclusive(similar to ∗ in separation logic) acc(c.f) acc(c.f) && c.f == 0 acc(c.f, ½) acc(c.f,½) && acc(c.f,½) acc(c1.f) && acc(c2.f,ε)⇒ c1 != c2

  21. Demo

  22. Permission Transfer Reloaded Idea of permission transfer generalises • Fork-join (transfer between threads) • Locks (transfer to/from lock invariant) • Message passing (pass permissions) Common operations • Gain permissions • Losepermissions foo(x) bar(x) ?

  23. Silver: Inhale and Exhale Statements Statement inhaleAmeans • Gain permissions required by A(e.g. acc(x.f)) • Assume logical constraints in A (e.g. x.f != 0) Statement exhaleAmeans • Assert and remove permissions required by A • Assert logical constraints in A • Havoc locations to which all permissions were removed(i.e. forget their values)

  24. ConcurrencyExamples

  25. Fork-Join Concurrency (Pseudo-Java) class Cell { int v voidadd(Cell c) { v = v + c.v } } void client() { Cellc1 = new Cell() c1.v = 1 Cellc2 = new Cell() c2.v = 2 Token tk = fork c1.add(c2)// ... join tk assert c1.v == 3 assertc2.v == 2 }

  26. Locks and @GuardedBy Annotations (Pseudo-Java) classSharedPair { @GuardedBy(“this”)int x, y void inc(int dx, intdy) {synchronized(this) { x = x + dx y = y + dy } } void swap() {intt = x x = y y = t } }  

  27. Lock Invariants (Pseudo-Java) classSharedPair { @GuardedBy(“this”, “x < y”)int x, y void inc(int dx, intdy) {synchronized(this) {assert x < y x = x + dx y = y + dy assertx < y } } } 

  28. Lock Invariants (Pseudo-Java) classSharedPair { @GuardedBy(“this”, “x < y”)int x, y void inc(int dx, intdy) {assertdx <= dysynchronized(this) {assert x < y x = x + dx y = y + dy assertx < y } } } 

  29. Viper: Our Verification Infrastructure Silver: • Intermediate Verification Language • Few (but expressive) constructs • Designed with verification and inference in mind Back-ends: Two verifiers;plans to develop inference, slicer Front-ends(proof of concept): • Chalice (concurrency research) • Scala (very small subset) • Java (VerCors, U Twente) • OpenCL(VerCors, U Twente) Front-ends Front-end Front-end Silver(IVL) Back-ends Front-end Automatic prover

  30. Viper: Our Verification Infrastructure Java(U Twente) OpenCL(U Twente) Chalice Scala generate Silver AST Static Analysis infer additionalspecifications verified by Carbon Silicon encodes in Boogie(Microsoft) queries queries Z3(Microsoft)

  31. Verification Condition Generation vs. Symbolic Execution Query prover once with full information (Carbon) one weakest precondition per method given to read by calculates Verifier WPs Prover VCG Program symbolically executeevery path througheach method maintains read by Verifier Program Symbolic State σ SE used by Prover query prover at every step if next statement is executable σ1 σ2 σ3 σ4 σ5 Query prover often with limited information (Silicon)

  32. Outlook Information hiding, abstraction and inheritance Unbounded (recursive) data structures Obligations – the dual to permissions Specification inference Encoding of high-level features • Immutable data (vs. permissions) • Lazy evaluation (vs. permissions) • Closures/higher order functions • Actor-based concurrency • Fine-grained locking, lock-free algorithms

  33. www.pm.inf.ethz.ch/research/viper.html Java(U Twente) OpenCL(U Twente) Chalice Scala generate Silver AST Static Analysis infer additionalspecifications verified by Carbon Silicon encodes in Boogie(Microsoft) queries queries Z3(Microsoft)

  34. You shouldn’t even be here!

  35. Fork-Join Concurrency (Pseudo-Java) class Cell { int v voidadd(Cell c) { v = v + c.v } } void client() { Cellc1 = new Cell() c1.v = 1 Cellc2 = new Cell() c2.v = 2 Token tk = fork c1.add(c2)// ... join tk assert c1.v == 3 assertc2.v == 2 }

  36. Fork-Join Concurrency (Silver) fieldv: Int method add(this: Ref, c: Ref) requires acc(this.v) && acc(c.v, ½) ensures acc(this.v) && acc(c.v, ½)ensures this.v == old(this.v) + old(c.v) { this.v := this.v+ c.v } method client() { // instantiate cells c1, c2; initialise with 1, 2 // Token tk = fork c1.add(c2) exhale acc(c1.v) && acc(c2.v, ½) // join tk inhale acc(c1.v) && acc(c2.v, ½) inhale c1.v == 1+ 2 assert c1.v == 3 && c2.v == 2 }

  37. Locks and @GuardedBy Annotations (Pseudo-Java) classSharedPair { @GuardedBy(“this”)int x, y void inc(int dx, intdy) {synchronized(this) { x = x = dx y = y = dy } } void swap() {intt = x x = y y = t } }  

  38. Locks and @GuardedBy Annotations (Silver) fieldx: Int fieldy: Int define inv(this) acc(this.x) && acc(this.y) method inc(this: Ref, dx: Int, dy: Int) { // begin synchronize(this) inhale inv(this) this.x := this.x + dx this.y:= this.y+ dy // end synchronize(this) exhale inv(this) } method swap(this: Ref) { var t: Int := this.x this.x== this.y this.y== t }  

  39. Lock Invariants (Pseudo-Java) classSharedPair { @GuardedBy(“this”, “x < y”)int x, y void inc(int dx, intdy) {synchronized(this) {assert x < y x = x = dx y = y = dy assertx < y } } } 

  40. Lock Invariants (Pseudo-Java) classSharedPair { @GuardedBy(“this”, “x < y”)int x, y void inc(int dx, intdy) {assertdx <= dy synchronized(this) {assert x < y x = x = dx y = y = dy assertx < y } } } 

  41. Lock Invariants (Silver) fieldx: Int fieldy: Int define inv(this) acc(this.x) && acc(this.y) && this.x <= this.y method inc(this: Ref, dx: Int, dy: Int)requires dx <= dy { // begin synchronize(this) inhale inv(this) this.x := this.x + dx this.y:= this.y+ dy // end synchronize(this) exhale inv(this) } 

More Related