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


Recommended