Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Verification with BLAST

Similar presentations


Presentation on theme: "Software Verification with BLAST"— Presentation transcript:

1 Software Verification with BLAST
Tom Henzinger Ranjit Jhala Rupak Majumdar BLAST = Berkeley Lazy Abstraction Software Verification Tool

2 Software Validation Large scale reliable software is hard to build and test Different groups write different components Integration testing is a nightmare

3 Property Checking Programmer gives partial specifications
Code checked for consistency w/ spec Different from program correctness Specifications are not complete Is there a complete spec for Word ? Emacs ?

4 Interface Usage Rules Rules in documentation
Order of operations & data access Resource management Incomplete, unenforced, wordy Violated rules  bad behavior System crash or deadlock Unexpected exceptions Failed runtime checks

5 Property 1: Double Locking
unlock “An attempt to re-acquire an acquired lock or release a released lock will cause a deadlock.” Calls to lock and unlock must alternate.

6 Property 2: Drop Root Privilege
[Chen-Dean-Wagner ’02] “User applications must not run with root privilege” When execv is called, must have suid  0

7 Property 3 : IRP Handler [Fahndrich] MPR3 CallDriver MPR completion
synch not pending returned SKIP2 IPC Skip return child status DC Complete request not Pend PPC prop N/A no prop start NP Pending NP MPR1 start P Mark Pending IRP accessible SKIP1 MPR2 [Fahndrich]

8 Does a given usage rule hold?
Undecidable! Equivalent to the halting problem Restricted computable versions are prohibitively expensive (PSPACE) Why bother ? Just because a problem is undecidable, it doesn’t go away! May be do this through an example

9 Plan Motivation Lazy Abstraction Technical Details

10 Example Example ( ) { 1: do{ lock(); old = new; q = q->next;
2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4: } while(new != old); 5: unlock (); return; lock unlock

11 What a program really is…
State Transition pc lock old new q  3  5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4  5  6  0x133a Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4: } while(new != old); 5: unlock (); return;}

12 The Safety Verification Problem
Error Safe Initial Is there a path from an initial to an error state ? Problem: Infinite state graph Solution : Set of states  logical formula

13 Idea 1: Predicate Abstraction
Predicates on program state: lock old = new States satisfying same predicates are equivalent Merged into one abstract state No. of abstract states is finite

14 Abstract States and Transitions
pc lock old new q  3  5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4  5  6  0x133a Theorem Prover lock old=new ~ lock ~ old=new

15 Abstraction State Existential Lifting Theorem Prover lock ~ lock
pc lock old new q  3  5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4  5  6  0x133a Theorem Prover lock old=new ~ lock ~ old=new Existential Lifting

16 Abstraction State lock ~ lock old=new ~ old=new 3: unlock(); new++;
pc lock old new q  3  5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4  5  6  0x133a lock old=new ~ lock ~ old=new

17 Analyze Abstraction Problem Analyze finite graph No false negatives
Over Approximate: Safe  System Safe No false negatives Problem Spurious counterexamples

18 Idea 2: Counterex.-Guided Refinement
Solution Use spurious counterexamples to refine abstraction !

19 Idea 2: Counterex.-Guided Refinement
Solution Use spurious counterexamples to refine abstraction 1. Add predicates to distinguish states across cut 2. Build refined abstraction Imprecision due to merge

20 Iterative Abstraction-Refinement
Solution Use spurious counterexamples to refine abstraction 1. Add predicates to distinguish states across cut 2. Build refined abstraction -eliminates counterexample 3. Repeat search Till real counterexample or system proved safe [Kurshan et al 93] [Clarke et al 00] [Ball-Rajamani 01]

21 Lazy Abstraction BLAST Safe Abstract Refine Trace Yes C Program No
Property Trace

22 Lazy Abstraction BLAST spec.opt Safe Trace Yes C Program Property No
Instrumented C file With ERROR label Safe spec.opt Property No Trace

23 Problem: Abstraction is Expensive
Reachable Problem #abstract states = 2#predicates Exponential Thm. Prover queries Observe Fraction of state space reachable #Preds ~ 100’s, #States ~ 2100 , #Reach ~ 1000’s

24 Solution1: Only Abstract Reachable States
Safe Solution Build abstraction during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries

25 Solution2: Don’t Refine Error-Free Regions
Problem #abstract states = 2#predicates Exponential Thm. Prover queries Solution Don’t refine error-free regions

26 Key Idea: Reachability Tree
Initial Unroll Abstraction 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 Find min infeasible suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 3

27 Key Idea: Reachability Tree
Initial Unroll Abstraction 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min infeasible suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 3 3 Error Free

28 Key Idea: Reachability Tree
Initial Unroll 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min spurious suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 8 3 3 1 8 1 Error Free S1: Only Abstract Reachable States S2: Don’t refine error-free regions SAFE

29 Build-and-Search Reachability Tree Predicates: LOCK 1 1 Example ( ) {
1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 1 Reachability Tree Predicates: LOCK

30 Build-and-Search Reachability Tree Predicates: LOCK 1 2 1 2
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); lock() old = new q=q->next 1 ~ LOCK 2 LOCK 1 2 Reachability Tree Predicates: LOCK

31 Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 1 2 3
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK [q!=NULL] 3 LOCK 1 2 3 Reachability Tree Predicates: LOCK

32 Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 4 1 2 3
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK 3 q->data = new unlock() new++ LOCK 4 ~ LOCK 4 1 2 3 Reachability Tree Predicates: LOCK

33 Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 5 5 4 1 2
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK 3 LOCK 4 ~ LOCK [new==old] 5 ~ LOCK 5 4 1 2 3 Reachability Tree Predicates: LOCK

34 Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 5 5 4 1 2
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK 3 LOCK 4 ~ LOCK 5 ~ LOCK 5 unlock() 4 ~ LOCK 1 2 3 Reachability Tree Predicates: LOCK

35 Analyze Counterexample
1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK lock() old = new q=q->next 2 LOCK [q!=NULL] 3 LOCK q->data = new unlock() new++ 4 ~ LOCK [new==old] 5 ~ LOCK 5 unlock() 4 ~ LOCK 1 2 3 Reachability Tree Predicates: LOCK

36 Analyze Counterexample
1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK old = new 2 LOCK 3 LOCK new++ 4 ~ LOCK [new==old] 5 ~ LOCK 5 Inconsistent 4 ~ LOCK new == old 1 2 3 Reachability Tree Predicates: LOCK

37 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 1 Reachability Tree Predicates: LOCK, new==old

38 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK lock() old = new q=q->next 2 LOCK , new==old 1 2 Reachability Tree Predicates: LOCK, new==old

39 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK , new==old LOCK , new==old 3 q->data = new unlock() new++ 4 ~ LOCK , ~ new = old 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

40 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK , new==old LOCK , new==old 3 4 ~ LOCK , ~ new = old [new==old] 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

41 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK , new==old LOCK , new==old 3 4 ~ LOCK , ~ new = old [new!=old] 1 ~ LOCK, ~ new == old 4 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

42 Repeat Build-and-Search
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 ~ LOCK 2 LOCK , new==old SAFE LOCK , new==old 3 4 4 ~ LOCK , ~ new==old LOCK , new==old 1 5 5 ~ LOCK, ~ new == old 4 4 4 1 ~ LOCK , new==old 2 3 Reachability Tree Predicates: LOCK, new==old

43 Key Idea: Reachability Tree
Initial Unroll 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min spurious suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 8 3 3 1 8 1 Error Free S1: Only Abstract Reachable States S2: Don’t refine error-free regions SAFE

44 Lazy Abstraction Problem: Abstraction is Expensive
Yes Safe C Program Abstract Refine No Property Trace Problem: Abstraction is Expensive Solution: 1. Abstract reachable states, Avoid refining error-free regions Key Idea: Reachability Tree

45 Plan Motivation Lazy Abstraction Technical Details
Q: How to compute “successors” ? Q: How to find predicates ?

46 Weakest Preconditions
WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P]

47 Weakest Preconditions
WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P] P[e/x] new+1 = old Assign new = new+1 x = e P new = old

48 Weakest Preconditions
WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P] C  P new=old  new=old Assume Branch [new=old] [c] P new = old

49 How to compute successor ?
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); LOCK , new==old 3 F OP 4 ? ~ LOCK , ~ new = old For each p Check if p is true (or false) after OP Q: When is p true after OP ? - If WP(p, OP) is true before OP ! - We know F is true before OP - Thm. Pvr. Query: F  WP(p, OP) Predicates: LOCK, new==old

50 How to compute successor ?
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); LOCK , new==old 3 F OP 4 ? For each p Check if p is true (or false) after OP Q: When is p false after OP ? - If WP(~ p, OP) is true before OP ! - We know F is true before OP - Thm. Pvr. Query: F  WP(~ p, OP) Predicates: LOCK, new==old

51 How to compute successor ?
Example ( ) { 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); LOCK , new==old 3 F OP 4 ? : new = old ~ LOCK , ~ new = old For each p Check if p is true (or false) after OP Predicate: new==old True ? (LOCK , new==old)  (new + 1 = old) NO False ? (LOCK , new==old)  (new + 1  old) YES

52 Lazy Abstraction Safe Abstract Refine Trace
Yes Safe C Program Abstract Refine No Property Trace Problem: #Preds grows w/ Program Size Solution: Localize pred. use, find where preds. needed Ctrex. Trace Pred. Map PC  Preds. Refine

53 #Predicates grows with program size
while(1){ 1: if (p1) lock() ; if (p1) unlock() ; 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } T F Tracking lock not enough Problem: p1,…,pn needed for verification Exponential reachable abstract states

54 #Predicates grows with program size
while(1){ 1: if (p1) lock() ; if (p1) unlock() ; 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } ~ LOCK LOCK, p1 ~ LOCK, ~ p1 ~ LOCK, p1 ~ LOCK, ~ p1 ~ LOCK p1p2 P1~p2 ~ p1 p2 ~p1 ~p2 2n Abstract States Problem: p1,…,pn needed for verification Exponential reachable abstract states

55 Predicates useful locally
while(1){ 1: if (p1) lock() ; if (p1) unlock() ; 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } ~ LOCK p1 LOCK , p1 ~ LOCK, ~ p1 ~ LOCK , p1 ~ LOCK ~ LOCK ~LOCK ~ LOCK , ~ p1 LOCK , p2 ~ LOCK , ~ p2 ~ LOCK p2 pn 2n Abstract States Solution: Use predicates only where needed Using Counterexamples: Q1. Find predicates Q2. Find where predicates are needed

56 Counterexample Traces
1: x = ctr; 2: ctr = ctr + 1; 3: y = ctr; 4: if (x = i-1){ 5: if (y != i){ ERROR: } } 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i)

57 Trace Formulas Thm: Trace is feasible , TF is satisfiable Trace
1: x = ctr 2: ctr = ctr+1 3: y = ctr 4: assume(x=i-1) 5: assume(yi) 1: x1 = ctr0 2: ctr1 = ctr0+1 3: y1 = ctr1 4: assume(x1=i0-1) 5: assume(y1i0) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Trace SSA Trace Trace Feasibility Formula Thm: Trace is feasible , TF is satisfiable

58 The Present State… … is all the information the
Trace 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) … is all the information the executing program has here State… 1. … after executing trace past (prefix) 2. … knows present values of variables 3. … makes trace future (suffix) infeasible At pc4, which predicate on present state shows infeasibility of future ?

59 What Predicate is needed ?
Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0 +1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0

60 What Predicate is needed ?
Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Relevant Information Predicate … 1. … after executing trace prefix … implied by TF prefix

61 What Predicate is needed ?
Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 x1 x1 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables … implied by TF prefix … on common variables

62 What Predicate is needed ?
Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables 3. … makes trace suffix infeasible … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

63 What Predicate is needed ?
Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables 3. … makes trace suffix infeasible … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

64 Interpolant = Predicate !
Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Predicate at 4: y= x+1 - Interpolate + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

65 Another interpretation …
Trace Formula x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Predicate at 4: y= x+1 After exec prefix - - Interpolate Can exec suffix + + y1 = x1 + 1 Unsat = Empty Intersection = Trace Infeasible Interpolant  = Overapprox. states after prefix that cannot execute suffix

66 Interpolant = Predicate !
Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Predicate at 4: y= x+1 - Interpolate + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

67 Interpolant = Predicate !
Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Predicate at 4: y= x+1 - Interpolate Q. How to compute interpolants ? … + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

68 Building Predicate Maps
2: x= ctr Trace Trace Formula - 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 Interpolate x1 = ctr0 + Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

69 Building Predicate Maps
2: x = ctr 3: x= ctr-1 Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 - Interpolate + x1= ctr1-1 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

70 Building Predicate Maps
2: x = ctr 3: x= ctr - 1 4: y= x + 1 Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 - + Interpolate y1= x1+1 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

71 Building Predicate Maps
2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: y = i Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 & ctr1 = ctr0+ 1 & y1 = ctr1 & x1 = i0 - 1 & y1  i0 - + Interpolate y1= i0 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

72 Local Predicate Use Verification scales …
Use predicates needed at location #Preds. grows with program size #Preds per location small Predicate Map 2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: y = i Verification scales … Local Predicate use Ex: 2n states Global Predicate use Ex: 2n states

73 Localizing Program kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7
Property3: IRP Handler Win NT DDK Localizing Program Lines* Previous Time(mins) Time (mins) Predicates Total Average kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7 diskprf 14k 5 13 140 10 cdaudio 18k 20 23 256 7.8 parport 61k DNF 74 753 8.1 parclss 138k 77 382 7.2 * Pre-processed

74 Lazy Abstraction Safe Abstract Refine Trace
Yes Safe C Program Abstract Refine No Property Trace Problem: #Preds grows w/ Program Size Solution: Localize pred. use, find where preds. needed Refine Trace Feas Formula Ctrex. Trace Proof of Unsat Pred. Map PC  Preds. Thm Pvr Interpolate

75 Plan Motivation Lazy Abstraction Demo Technical Details
Q: How to compute “successors” ? Q: How to find predicates ? Q: How to analyze (recursive) procedures ? Q: How to analyze long traces ?

76 An example main(){  1: if (flag){ 2: y = inc(x,flag);
3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv;

77 Inline Calls in Reach Tree
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; Initial 1 2 4 1,2 1,4 2,2 3,2 2,4 3,4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 4,2 4,2 4,4 4,4 3 3 5 5

78 Inline Calls in Reach Tree
Problem Repeated analysis for “inc” Exploding call contexts Initial 1 2 4 int x; //global f1(){ 1: x = 0; 2: if(*) f2(); 3: else f2(); 4: if (x<0) ERROR; return; } 1,2 1,4 f2(){ 1: if(*) f3(); 2: else f3(); return; } f3(){ 1: if(*) f4(); 2: else f4(); return; } 2,2 3,2 2,4 3,4 f4(){ 1: if(*) f5(); 2: else f5(); return; } fn(){ 1: x ++; return; } 4,2 4,2 4,4 4,4 3 3 5 5 2n nodes in Reach Tree

79 Inline Calls in Reach Tree
Problem Repeated analysis for “inc” Exploding call contexts Cyclic call graph (Recursion) Infinite Tree! Initial 1 2 4 1,2 1,4 2,2 3,2 2,4 3,4 4,2 4,2 4,4 4,4 3 3 5 5

80 Solution : Procedure Summaries
Summaries: Input/Output behavior Plug summaries in at each callsite … instead of inlining entire procedure [Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95] Summary = set of (F  F’) F : Precondition formula describing input state F’ : Postcondition formula describing output state

81 Solution : Procedure Summaries
Summaries: Input/Output behavior Plug summaries in at each callsite … instead of inlining entire procedure [Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95, Ball-Rajamani 01] Summary = set of (F  F’) F : Precondition formula describing input state F’ : Postcondition formula describing output state inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; (~ sign=0  rv > a) (sign = 0  rv < a) Q. How to compute, use summaries ?

82 Abstraction with Summaries
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main 1 [flag!=0] 2 ~ flag=0 a=x sign=flag ~ sign=0 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a

83 Abstraction with Summaries
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 [sign!=0] 2 ~ flag=0 ~ sign=0 2 a=x sign=flag rv=a+1 ~ sign=0 rv>a 4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a),

84 Summary Successor main inc Predicates: flag=0 , y>x , y<z
1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 2 a=x sign=flag ~ flag=0 2 assume rv>a 3 y>x y=rv rv>a 4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a),

85 Abstraction with Summaries
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 [flag==0] [sign=0] 2 4 ~ flag=0 flag=0 2 3 y>x 3 sign=0 rv>a 4 [y<=x] a=z sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a),

86 Abstraction with Summaries
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 1 sign=0 2 4 ~ flag=0 flag=0 2 3 2 3 y>x 3 sign=0 rv>a 4 4 rv<a a=z sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a), (sign=0  rv<a)

87 Summary Successor main inc Predicates: flag=0 , y>x , y<z
1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 1 sign=0 2 4 ~ flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a a=x sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; assume rv<a y=rv Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a), (sign=0  rv<a)

88 Abstraction with Summaries
main(){ 1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 ~ sign=0 1 1 sign=0 2 4 ~ flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a [y>=z] inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a), (sign=0  rv<a)

89 Another Call … main inc Predicates: flag=0 ,y>x,y<z, y1>z1
1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } 6: y1 = inc(z1,1); 7: if (y1<=z1) ERROR; return; main inc 1 ~ sign=0 1 1 sign=0 2 4 ~ flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 6 6 a=z1 sign=1 ~ sign=0 Predicates: flag=0 ,y>x,y<z, y1>z1 sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a), (sign=0  rv<a)

90 Another Call … SAFE main inc
1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } 6: y1 = inc(z1,1); 7: if (y1<=z1) ERROR; return; main inc 1 ~ sign=0 1 1 sign=0 2 4 ~ flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 6 6 SAFE a=z1 sign=1 y1>z1 7 assume rv>a y1=rv Predicates: flag=0 ,y>x,y<z, y1>z1 sign=0 , rv>a , rv<a Summary: (~ sign=0  rv>a), (sign=0  rv<a)

91 Plan Motivation Lazy Abstraction Demo Technical Details
Q: How to compute “successors” ? Q: How to find predicates ? Q: How to analyze (recursive) procedures ? Q: How to analyze long traces ?

92 Example Assume f always terminates Example ( ) { 1:c = 0;
ERR is reachable a and x are unconstrained Any feasible path to error must unroll the loop 1000 times AND find feasible paths through f Any other path must be dismissed as a false positive Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; }

93 Example Intuitively, the for loop is irrelevant Example ( ) { 1:c = 0;
ERR reachable as long as there exists some path from 2 to 4 that does not modify a or x Can we use static analysis to precisely report a statement is reachable without finding a feasible path? Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; }

94 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ i¸1000 4 4 a>0 a>0 5 5 x==0 x==0

95 Path Slice, Formally The path slice of a program path  is a subsequence of the edges of  such that if the sequence of operations along the subsequence is: infeasible, then  is infeasible, and feasible, then the last location of  is reachable (but not necessarily along )

96 Computing Path Slices Intuitively, drop some edges, but leave branches that must be taken to reach the target, and assignments that feed into the branch conditions Backward dataflow over the path, tracking at each node step location: source location of the last edge along the path added to the slice live variables: set of relevant variables whose values determine whether or not the target is reachable along the suffix

97 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
A conditional is taken if either (1) there is a path from the current node to the step location on which a live variable is modified, or (2) the current node does not post-dominate the step location 1 Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ i¸1000 4 a>0 5 x==0 ERR, {}

98 Conditionals current current x2 Live X = … step step

99 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
A conditional is taken if either (1) there is a path from the current node to the step location on which a live variable is modified, or (2) the current node does not post-dominate the step location 1 Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ Live = (Live n Wr(op)) [ Rd(op) i¸1000 4 a>0 5 x==0 ERR, {}

100 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ i¸1000 4 a>0 5 x==0 ERR, {}

101 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ 4, {x, a} i¸1000 4 4, {x, a} a>0 5 5, {x} x==0 ERR, {}

102 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 An assignment is taken if the assigned variable is in the Live set 2 i = 1 2’ i<1000 3 c = c + f(i);i++ 2’ 4, {x, a} i¸1000 4 4, {x, a} a>0 5 5, {x} x==0 ERR, {}

103 Example Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++)
3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; } c = 0 2 4, {x, a} i = 1 4, {x, a} 2’ i<1000 4, {x, a} 3 c = c + f(i);i++ 2’ 4, {x, a} i¸1000 4 4, {x, a} a>0 5 5, {x} x==0 ERR, {}

104 Slice Example ( ) { 1:c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i);
4:if (a>0) { 5: if (x==0) { ERR: ; } 4 a>0 5 x==0

105 Example 2: Infeasible Path
c = 0 1 i = 1 2 i¸1000 2’ 3 c=c+f(i);i++ 4 i<1000 a>0 x==0 5 ERR, {} 5, {x} 4, {x, a} Example ( ) { A:if (a>0) { B: x = 1; } 1: c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ;

106 Example 2: Infeasible Path
A:if (a>0) { B: x = 1; } 1: c = 0; 2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; A, {a} A a>0 B, {a} B x = 1 1 4, {x, a} c = 0 2 4, {x, a} i = 1 Live = (Live n Wr(op)) [ Rd(op) 4, {x, a} 2’ i<1000 4, {x, a} 3 c = c + f(i);i++ 2’ 4, {x, a} i¸1000 4 4, {x, a} a>0 5 5, {x} x==0 ERR, {}

107 Slice Example ( ) { A:if (a>0) { B: x = 1; } 1: c = 0;
2:for(i=1;i<1000;i++) 3: c = c + f(i); 4:if (a>0) { 5: if (x==0) { ERR: ; A a>0 B x = 1 1 Infeasible Slice implies Infeasible trace 4 a>0 5 x==0

108 Lazy Abstraction: Summary
Yes Safe Abstract C Program Path Slice Refine No Property Trace

109 Lazy Abstraction: Summary
Predicates: Abstract infinite program states Counterexample-guided Refinement: Find predicates tailored to prog, property Abstraction : Expensive Reachability Tree, Procedure summaries Refinement : Find predicates, use locations Slice irrelevant details Proof of unsat of TF + Interpolation


Download ppt "Software Verification with BLAST"

Similar presentations


Ads by Google