An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems...

41
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)

description

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)

Transcript of An Introduction to Automated Program Verification with Permission Logics 15 th May 2015, Systems...

Page 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,

An Introduction to Automated Program

Verification with Permission Logics

15th May 2015, Systems Group, ETH Zurich

Uri Juhasz, Ioannis Kassios, Peter Müller, Milos Novacek,Malte Schwerhoff, Alex Summers (and several students)

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

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)

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

4

Modularityclass 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}

?

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

5

Specificationsclass 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}

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

6

Reasoning with Specificationsclass 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} ?

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

7

An Incorrect Implementationclass 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}

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

8

Strengthening Specificationsclass 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}

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

9

Strengthening Specificationsvoid 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 }}

?

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

10

Aliasingclass 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}

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

11

Reason about Shared State(Including Data Races)

andControl Aliasing

Challenges

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

13

Modular Static Verification + Shared State

foo(x) bar(x)

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

14

Modular Static Verification + Shared State

foo(x) bar(x)

?

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

15

Modular Static Verification + Shared State

foo(x) bar(x)

??

?

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

16

Permissions

foo(x) bar(x)

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

17

Permission Transfer

foo(x) bar(x)

?

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

18

Permission Transfer

foo(x) bar(x)

??

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

19

Fractional Permissions

foo(x) bar(x)

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

20

Splitting Fractional Permissions

foo(x) bar(x)

?

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

21

Merging Fractional Permissions

foo(x) bar(x)

?

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

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

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

23

Demo

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

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)

?

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

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)

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

26

ConcurrencyExamples

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

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}

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

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

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

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

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

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

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

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-endBack-ends

Automaticprover

Front-endFront-endFront-ends

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

32

Silver AST

Viper: Our Verification Infrastructure

SiliconCarbon

Boogie(Microsoft)

Z3(Microsoft)

verified by

encodes in

queries

queries

generate

Static Analysis

infer additionalspecifications

ChaliceOpenCL

(U Twente)

ScalaJava(U

Twente)

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

33

Query prover once with full information (Carbon)

Verification Condition Generation vs. Symbolic Execution

Program Verifierread by calculates Provergiven toWPs

one weakest precondition per

methodVCG

Query prover often with limited information (Silicon)

Program Verifier read

bymaintains Symbolic State

σ

symbolically executeevery path through

each method

query prover at every step if next statement is

executable

Proverused by

σ1

σ2

σ3

σ4

σ5

SE

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

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

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

35

Silver AST

www.pm.inf.ethz.ch/research/viper.html

SiliconCarbon

Boogie(Microsoft)

Z3(Microsoft)

verified by

encodes in

queries

queries

generate

Static Analysis

infer additionalspecifications

ChaliceOpenCL

(U Twente)

ScalaJava(U

Twente)

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

36

You shouldn’t even be here!

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

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}

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

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}

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

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

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

40

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

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

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

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

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

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

43

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