an introduction to automated program verification with permission logics 15 th may 2015, systems...

Post on 17-Jan-2018

223 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

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)

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

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}

?

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}

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

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}

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}

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

?

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}

11

Reason about Shared State(Including Data Races)

andControl Aliasing

Challenges

13

Modular Static Verification + Shared State

foo(x) bar(x)

14

Modular Static Verification + Shared State

foo(x) bar(x)

?

15

Modular Static Verification + Shared State

foo(x) bar(x)

??

?

16

Permissions

foo(x) bar(x)

17

Permission Transfer

foo(x) bar(x)

?

18

Permission Transfer

foo(x) bar(x)

??

19

Fractional Permissions

foo(x) bar(x)

20

Splitting Fractional Permissions

foo(x) bar(x)

?

21

Merging Fractional Permissions

foo(x) bar(x)

?

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

Demo

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

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

ConcurrencyExamples

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

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

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

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

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

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)

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

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

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)

36

You shouldn’t even be here!

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

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

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

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}

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

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

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

top related