software verification with blast

37
Software Software Verification with Verification with Blast Blast Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar, George Necula, Grégoire Sutre, Wes Weimer UC Berkeley

Upload: ciaran-adams

Post on 02-Jan-2016

42 views

Category:

Documents


1 download

DESCRIPTION

Software Verification with Blast. Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar, George Necula, Grégoire Sutre, Wes Weimer UC Berkeley. Motivation. Verification of systems code Locking disciplines Interface specifications Essential for correct operation High rate of bugs - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Software Verification with Blast

Software Verification Software Verification with Blastwith Blast

Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar,George Necula, Grégoire Sutre, Wes Weimer

UC Berkeley

Page 2: Software Verification with Blast

2

MotivationMotivation

Verification of systems codeLocking disciplinesInterface specifications

Essential for correct operationHigh rate of bugs

Temporal propertiesRequire path-sensitive analysisSwamped by false positives

Really hard to check

Page 3: Software Verification with Blast

3

Model CheckingModel Checking

Doesn’t scale to low level implementations

Can only model check “abstractions”

Requires human intervention …

Abstract – Check – Refine LoopMicrosoft SLAM Project[Clarke et. al. 00], [Saidi 00]

Page 4: Software Verification with Blast

4

Abstract-Check-Refine LoopAbstract-Check-Refine Loop

Abstract

Explanation

YES (Trace)

BUG

Feasible

???

Check

Refine

NO

SAFE

Seed Abstraction

Program

Abstraction

InfeasibleWhy infeasible ?

Is model unsafe ?

Page 5: Software Verification with Blast

5

Model Checking 101Model Checking 101

ERROR STATES

Init

SYSTEM’S STATE SPACE

Keep searching successors until …Hit error states: report “bug” !Add no new successors: report “safe”Could take a long time …

Page 6: Software Verification with Blast

6

Model Checking & AbstractionModel Checking & Abstraction

Problem: Far too many states Iterations don’t terminate !Solution: Abstract …

ERROR STATES

Init

Page 7: Software Verification with Blast

7

ERROR STATES

Init

Model Checking & AbstractionModel Checking & Abstraction

Problem: Abstraction too coarseSolution: Refine abstraction

Make boxes smaller

Page 8: Software Verification with Blast

8

ERROR STATES

Init

Model Checking & AbstractionModel Checking & Abstraction

Problem: Abstraction too coarseSolution: Refine abstraction

Make boxes smaller

Page 9: Software Verification with Blast

9

Abstract Only Where RequiredAbstract Only Where Required

ERROR STATES

Abstraction is very expensive Why abstract regions that are never visited ?

Init

Reachable States

On-the-fly abstraction: driven by the search

Page 10: Software Verification with Blast

10

Refine Only Where RequiredRefine Only Where Required

Why be precise everywhere ?Don’t refine error-free regions

ERROR STATES

Init

ERROR FREE

Page 11: Software Verification with Blast

11

Refine Only Where RequiredRefine Only Where Required

Why be precise everywhere ?Don’t refine error-free regions

Different precision for different regions Local Refinement : driven by the search

ERROR STATES

Init

ERROR FREE

Page 12: Software Verification with Blast

12

How to improve How to improve

Abstract only where requiredReachable state space is very sparseConstruct the abstraction on-the-fly

Use greater precision only where requiredDifferent precisions/abstractions for different regionsRefine locally

Reuse work from earlier phasesBatch-oriented ) lose work from previous runsIntegrate the three phases

Exploit control flow structure

Page 13: Software Verification with Blast

13

ExampleExample

Q: Is Error Reachable ?

Example ( ) {1: if (*) { 7: do { got_lock = 0;8: if (*) {9: lock(); got_lock ++; }10: if (got_lock) {11: unlock(); }12: } while (*) ; }2: do { lock(); old = new;3: if (*) {4: unlock(); new ++; }5: } while ( new != old);6: unlock (); return;}

unlock() lock()

lock()

unlock()

Page 14: Software Verification with Blast

14

Example ( ) {1: if (*) { 7: do { got_lock = 0;8: if (*) {9: lock(); got_lock ++; }10: if (got_lock) {11: unlock(); }12: } while (*) ; }2: do { lock(); old = new;3: if (*) {4: unlock(); new ++; }5: } while ( new != old);6: unlock (); return;}

Example:CFAExample:CFA1

3

lock();

old = new

2 7

[>][>]

4

5

[>]

[>]

unlock()

new++

6

[new==old]

[new!=old]

retunlock()

Page 15: Software Verification with Blast

15

Example ( ) {1: if (*) { 7: do { got_lock = 0;8: if (*) {9: lock(); got_lock ++; }10: if (got_lock) {11: unlock(); }12: } while (*) ; }2: do { lock(); old = new;3: if (*) {4: unlock(); new ++; }5: } while ( new != old);6: unlock (); return;}

Example:CFAExample:CFA

8

10

9

12

11

7

1

3

2

4

5

6

ret

got_lock=0

[>]

[>]

lock();

got_lock++

[got_lock == 0]

[got_lock != 0]

unlock()

[>] [>]

Page 16: Software Verification with Blast

16

Example:CFAExample:CFA

Q: Is Error Reachable ?

Example ( ) {1: if (*) { 7: do { got_lock = 0;8: if (*) {9: lock(); got_lock ++; }10: if (got_lock) {11: unlock(); }12: } while (*) ; }2: do { lock(); old = new;3: if (*) {4: unlock(); new ++; }5: } while ( new != old);6: unlock (); return;}

8

10

9

12

11

7

1

3

2

4

5

6

retunlock() lock()

lock()

unlock()

Page 17: Software Verification with Blast

17

Step 1: SearchStep 1: Search

Set of predicates:

LOCK=0, LOCK=1

1 LOCK=0

2 LOCK=0

4 LOCK=1

6 LOCK=0

[>]

lock();

old = new

[>]

unlock()

new++

[new==old]

unlock()

8

10

9

12

11

7

1

3

2

4

5

6

ret

5 LOCK=0

3 LOCK=1

Err LOCK=0

Page 18: Software Verification with Blast

18

Q: When can:

Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample

1 LOCK=0

2 LOCK=0

3 LOCK=1

4 LOCK=1

5 LOCK=0

6 LOCK=0

Err LOCK=0

8

10

9

12

11

7

1

3

2

4

5

6

ret

n Errops

States that can = wp( >,ops)

States at node n = Rn

) check:

Rn Æ wp( >,ops) = ? ?

Page 19: Software Verification with Blast

19

Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample

1 LOCK=0

2 LOCK=0

3 LOCK=1

4 LOCK=1

5 LOCK=0

6 LOCK=0

Err LOCK=0

lock();

old = new

[>]

unlock();

new++

[new==old]

unlock()

LOCK=0

LOCK=0

LOCK=0 Æ new = old

LOCK=0 Æ new+1 = new

LOCK=1 Æ new+1 = old

LOCK=1 Æ new +1 = old

8

10

9

12

11

7

1

3

2

4

5

6

ret

Rn Æ wp (>,ops) = ? ?

Page 20: Software Verification with Blast

20

Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample

1 LOCK=0

2 LOCK=0

3 LOCK=1

4 LOCK=1

5 LOCK=0

6 LOCK=0

Err LOCK=0

lock();

old = new

[>]

unlock();

new++

[new==old]

unlock()

LOCK=0

LOCK=0

LOCK=0 Æ new = old

LOCK=0 Æ new+1 = new

LOCK=1 Æ new+1 = old

LOCK=1 Æ new +1 = old

8

10

9

12

11

7

1

3

2

4

5

6

ret

Track the predicate:

new = old

Page 21: Software Verification with Blast

21

Step 3: Resume searchStep 3: Resume search1LOCK=0

2LOCK=0

4LOCK=1 Æ new = old

lock();

old = new

[>]

unlock()

new++

[new==old]

? 6[new!=old]

2

LOCK=0 Æ : new = old µ LOCK =0

Set of predicates:

LOCK=0, LOCK=1

New predicate:

new = old,

8

10

9

12

11

7

1

3

2

4

5

6

ret

5LOCK=0 Æ : new = old

3LOCK=1 Æ new = old

Page 22: Software Verification with Blast

22

Step 3: Resume searchStep 3: Resume search1LOCK=0

2LOCK=0

3LOCK=1 Æ new = old

4LOCK=1 Æ new = old

5LOCK=0 Æ : new = old

? 6 2

LOCK=0 Æ : new = old

[>]

5LOCK=1 Æ new=old

6

[new==old][new!=old]

1

?unlock()

8

10

9

12

11

7

1

3

2

4

5

6

ret

Set of predicates:

LOCK=0, LOCK=1

New predicate:

new = old

retLOCK=0Æ new=old

Page 23: Software Verification with Blast

23

Example ( ) {1: if (*) { 7: do { got_lock = 0;8: if (*) {9: lock(); got_lock ++; }10: if (got_lock) {11: unlock(); }12: } while (*) ; }2: do { lock(); old = new;3: if (*) {4: unlock(); new ++; }5: } while ( new != old);6: unlock (); return;}

Example:CFAExample:CFA

8

10

9

12

11

7

1

3

2

4

5

6

ret

got_lock=0

[>]

[>]

lock();

got_lock++

[got_lock == 0]

[got_lock != 0]

unlock()

[>] [>]

Page 24: Software Verification with Blast

24

Step 4: Search Right BranchStep 4: Search Right Branch1 LOCK=0

[>]

2LOCK=0 7 LOCK=0

[>]

Err

8

10

9

12

11

7

1

3

2

4

5

6

ret

Set of predicates:

LOCK=0, LOCK=1

New predicate: (from trace)

got_lock = 0

Page 25: Software Verification with Blast

25

Leaves Covered (Reuse work)Leaves Covered (Reuse work)1 LOCK=0

2LOCK=0 7 LOCK=0

222

LOCK=0 Æ …

COVERED !

Leaves covered:

Avoid repeating search when paths merge

8

10

9

12

11

7

1

3

2

4

5

6

ret

Page 26: Software Verification with Blast

27

Reachability TreeReachability Tree1LOCK=0

2LOCK=0

3LOCK=1 Æ new = old

4LOCK=1 Æ new = old

5LOCK=0 Æ : new = old

? 6 2

5LOCK=1 Æ new=old

6 1

?

retLOCK=0Æ new=old

8

12

7

10

10

11

1211

9

LOCK=0

12

82

LOCK=0 Æ got_lock=0

LOCK=1 Æ got_lock!=0

LOCK=0 Æ got_lock=0

LOCK=0 Æ got_lock=0

?

?

Page 27: Software Verification with Blast

28

InvariantsInvariants1LOCK=0

2LOCK=0

3LOCK=1 Æ new = old

4LOCK=1 Æ new = old

5LOCK=0 Æ : new = old

? 6 2

5LOCK=1 Æ new=old

6 1

?

retLOCK=0Æ new=old

Regions in the tree are invariants:

Invariant Inv (n) for node n =

Disjunction of all node-n regions in the tree

Inv (5) is:

LOCK=0 Æ : new = old Ç LOCK=1 Æ new=old

Inv (6) is:

LOCK=1 Æ new=old

Page 28: Software Verification with Blast

29

Proof GenerationProof Generation1

3

2

4

5

6

ret

LOCK=0 Æ : new = oldÇ

LOCK=1 Æ new=old [new==old]

[new!=old]

Use the invariants from the tree

Verification Conditions for correctness

1. Pre ) Inv (1)

2. Inv (e) = false for error node e

3. Post (Inv (j), cjk ) ) Inv (k)

These can be formalized as in PCC

1. Inv (1) contains Pre as disjunct

2. Error node not in tree

Page 29: Software Verification with Blast

30

Proof Generation IIProof Generation II1

3

2

4

5

6

ret

LOCK=0 Æ : new = oldÇ

LOCK=1 Æ new=old [new==old]

[new!=old]

Prove : Post ( Inv (i) , cij ) ) Inv (j)

Use the tree to break the proof:

Post(AÇ B, c) ) D Ç E

becomes:

Post (A,c) ) D and Post (B,c) ) E

Example: Post (Inv (5), new==old) ) Inv (6)

LOCK=1 Æ new=old

Post (LOCK=0 Æ : new=old, new==old) ) LOCK=1Æ new=old

Post(LOCK=1 Æ new=old, new==old) ) LOCK=1 Æ new=old

Page 30: Software Verification with Blast

31

Proof Generation IIProof Generation II1

3

2

4

5

6

ret

LOCK=0 Æ : new = oldÇ

LOCK=1 Æ new=old [new==old]

[new!=old]

Prove : Post ( Inv (i) , cij ) ) Inv (j)

Use the tree to break the proof:

Post(AÇ B, c) ) D Ç E

becomes:

Post (A,c) ) D and Post (B,c) ) E

But these were computed in the forward search!

Example: Post (Inv (5), new==old) ) Inv (6)

LOCK=1 Æ new=old

false ) LOCK=1Æ new=old

LOCK=1 Æ new=old) LOCK=1 Æ new=old

Page 31: Software Verification with Blast

33

BLASTBLAST

LAZY

ABSTRACTION

Berkeley Lazy Abstraction Software verification Tool10K Lines of OcamlAnalyze Linux/Windows Device Drivers

CIL

(C ! CFA)

REGION

STRUCTURE

BDD Engine

(Boolean ops)

Simplify

(Post#)

Vampyre

(focus)

Proof Gen

(PCC)

Page 32: Software Verification with Blast

34

MPR3

CallDriver

MPRcompletion

synch

not pending returned

SKIP2

IPCCallDriver

Skip returnchild status

DC

Completerequest

returnnot Pend

PPCprop

completion

CallDriver

N/A

no propcompletion

CallDriver

start NP

returnPending

NP

MPR1

MPRcompletion

SKIP2

IPCCallDriver

CallDriver

DC

Completerequest

PPCprop

completion

CallDriver

N?A

no propcompletion

CallDriver

start P Mark Pending

IRP accessible N/A

synch

SKIP1CallDriver

SKIP1Skip

MPR2 MPR1

NP

MPR3

CallDrivernot pending returned

MPR2

synch

From the SLAM project

Page 33: Software Verification with Blast

35

ExperimentsExperiments

Windows Drivers (IRP Spec – 22 states)

Program Lines Predicates Time Proof

floppy.c 17386 62 37 35 min

17386 93 44 21 min 60K

parport.c 61781 193 50 33 min 103K

mouclass.c 17352 57 46 1 min

cdaudio.c 17798 85 45 23 min 156K

kbfiltr.c 12131 54 40 1 min

12131 12 8 10 sec 7K

Page 34: Software Verification with Blast

36

Experiments Experiments : Linux Locking: Linux Locking

Program Lines Predicates Time Proof

ide.c 18131 5 5 4 sec 253

aironet.c 18152 17 11 4 min

aha152x.c 17736 2 2 20 sec

tlan.c 16505 5 4 7 min 405

Page 35: Software Verification with Blast

37

Why Abstract Lazily ?Why Abstract Lazily ?

Reach set is very sparseAbstract on-the-flyOnly the reachable regionRequires very fast post#

Exploit Control-Flow StructureFree partitioning of state spacePartition preds: different abstractionsRefine locally: don’t repeat old work

Page 36: Software Verification with Blast

38

Problems/Future workProblems/Future work

Engineering IssuesProgram analysis Partitioning by partial evaluation

Theory of counterexample driven refinement

for all linear and branching time logics

Page 37: Software Verification with Blast

44

“BLAST! This is why I hate flying!”- Jedi Master Obi-Wan Kenobi in Episode II: Attack of the

Clones, 2002