Presentation is loading. Please wait.

Presentation is loading. Please wait.

An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems Group, ETH Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,

Similar presentations


Presentation on theme: "An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems Group, ETH Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,"— Presentation transcript:

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

2 Outline 1.Motivation 2.Permissions 3.Demo 4.Concurrency (Demo) 5.Tools 6.Outlook

3 3 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) assert c1.v == 3 assert c2.v == 2 } Goal: Check assertions statically Challenges: − Whole-code analysis is expensive − Dynamic dispatch (inheritance; open-world assumption)

4 4 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 assert c2.v == 2 } ?

5 5 Specifications class Cell { int v void add(Cell c) requires c != null ensures 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 assert c2.v == 2 }

6 6 Reasoning with Specifications class Cell { int v void add(Cell c) requires c != null ensures 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 assert c2.v == 2 } ?

7 7 An Incorrect Implementation class Cell { int v void add(Cell c) requires c != null ensures 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 assert c2.v == 2 }  

8 8 Strengthening Specifications class Cell { int v void add(Cell c) requires c != null ensures 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 assert c2.v == 2 } 

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

10 10 Aliasing class Cell { int v void add(Cell c) requires c != null ensures 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(c1) // ensures c1.v == 1 + 1 // ensures c1.v == 1 assert c1.v == 3 assert c2.v == 2 }   

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

12 Use permissions to control access to shared state Permissions only exist statically, not at run-time 12 Permission-Based Verification

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

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

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

16 16 Permissions foo(x)bar(x)

17 17 Permission Transfer foo(x)bar(x) ?

18 18 Permission Transfer foo(x)bar(x) ?

19 19 Fractional Permissions foo(x)bar(x)

20 20 Splitting Fractional Permissions foo(x)bar(x) ?

21 21 Merging Fractional Permissions foo(x)bar(x) ?

22 22 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, ½) acc(c.f) acc(c.f) && c.f == 0 acc(c.f, ½) acc(c1.f) && acc(c2.f, ε ) ⇒ c1 != c2

23 23 Demo

24 24 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 − Lose permissions foo(x)bar(x) ?

25 25 Silver: Inhale and Exhale Statements Statement inhale A means −Gain permissions required by A (e.g. acc(x.f) ) −Assume logical constraints in A (e.g. x.f != 0 ) Statement exhale A means −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)

26 26 Concurrency Examples

27 27 Fork-Join Concurrency (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 Token tk = fork c1.add(c2) //... join tk assert c1.v == 3 assert c2.v == 2 }

28 28 Locks and @GuardedBy Annotations (Pseudo- Java) class SharedPair { @GuardedBy(“this”) int x, y void inc(int dx, int dy) { synchronized(this) { x = x + dx y = y + dy } void swap() { int t = x x = y y = t } 

29 29 Lock Invariants (Pseudo-Java) class SharedPair { @GuardedBy(“this”, “x < y”) int x, y void inc(int dx, int dy) { synchronized(this) { assert x < y x = x + dx y = y + dy assert x < y } 

30 30 Lock Invariants (Pseudo-Java) class SharedPair { @GuardedBy(“this”, “x < y”) int x, y void inc(int dx, int dy) { assert dx <= dy synchronized(this) { assert x < y x = x + dx y = y + dy assert x < y }

31 31 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) Silver (IVL) Front-end Back-ends Automatic prover Front-end Front-ends

32 Silver AST 32 Viper: Our Verification Infrastructure SiliconCarbon Boogie (Microsoft) Z3 (Microsoft) verified by encodes in queries generate Static Analysis infer additional specifications Chalice OpenCL (U Twente) Scala Java (U Twente)

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

34 34 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

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

36 36 You shouldn’t even be here!

37 37 Fork-Join Concurrency (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 Token tk = fork c1.add(c2) //... join tk assert c1.v == 3 assert c2.v == 2 }

38 38 Fork-Join Concurrency (Silver) field v: 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 }

39 39 Locks and @GuardedBy Annotations (Pseudo- Java) class SharedPair { @GuardedBy(“this”) int x, y void inc(int dx, int dy) { synchronized(this) { x = x = dx y = y = dy } void swap() { int t = x x = y y = t } 

40 40 Locks and @GuardedBy Annotations (Silver) field x: Int field y: 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 } 

41 41 Lock Invariants (Pseudo-Java) class SharedPair { @GuardedBy(“this”, “x < y”) int x, y void inc(int dx, int dy) { synchronized(this) { assert x < y x = x = dx y = y = dy assert x < y } 

42 42 Lock Invariants (Pseudo-Java) class SharedPair { @GuardedBy(“this”, “x < y”) int x, y void inc(int dx, int dy) { assert dx <= dy synchronized(this) { assert x < y x = x = dx y = y = dy assert x < y }

43 43 Lock Invariants (Silver) field x: Int field y: 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) }


Download ppt "An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems Group, ETH Zurich Uri Juhasz, Ioannis Kassios, Peter Müller,"

Similar presentations


Ads by Google