Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Software Verification with Blast Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar, George Necula, Grégoire Sutre, Wes Weimer UC Berkeley."— Presentation transcript:

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

2 2 Motivation Verification of systems code Locking disciplines Interface specifications Essential for correct operation High rate of bugs Temporal properties Require path-sensitive analysis Swamped by false positives Really hard to check

3 3 Model Checking Doesn’t scale to low level implementations Can only model check “abstractions” Requires human intervention … Abstract – Check – Refine Loop Microsoft SLAM Project [Clarke et. al. 00], [Saidi 00]

4 4 Abstract-Check-Refine Loop Abstract Explanation YES (Trace) BUG Feasible ??? Check Refine NO SAFE Seed Abstraction Program Abstraction Infeasible Why infeasible ? Is model unsafe ?

5 5 Model 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 …

6 6 Model Checking & Abstraction Problem: Far too many states Iterations don ’ t terminate ! Solution: Abstract … ERROR STATES Init

7 7 ERROR STATES Init Model Checking & Abstraction Problem: Abstraction too coarse Solution: Refine abstraction Make boxes smaller

8 8 ERROR STATES Init Model Checking & Abstraction Problem: Abstraction too coarse Solution: Refine abstraction Make boxes smaller

9 9 Abstract 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

10 10 Refine Only Where Required Why be precise everywhere ? Don ’ t refine error-free regions ERROR STATES Init ERROR FREE

11 11 Refine 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

12 12 How to improve Abstract only where required Reachable state space is very sparse Construct the abstraction on-the-fly Use greater precision only where required Different precisions/abstractions for different regions Refine locally Reuse work from earlier phases Batch-oriented ) lose work from previous runs Integrate the three phases Exploit control flow structure

13 13 Example 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() unlock()

14 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:CFA 1 3 lock(); old = new 2 7 [>][>][>][>] 4 5 [>][>] [>][>] unlock() new++ 6 [new==old] [new!=old] ret unlock()

15 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: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() [>][>] [>][>]

16 16 Example: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 ret unlock()lock() unlock()

17 17 Step 1: Search Set of predicates: LOCK=0, LOCK=1 1 LOCK=0 2 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

18 18 Q: When can: Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 8 10 9 12 11 7 1 3 2 4 5 6 ret n Err ops States that can = wp( >,ops) States at node n = R n ) check: R n Æ wp( >,ops) = ? ?

19 19 Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 LOCK=0 Æ new = old LOCK=0 Æ new+1 = new LOCK=1 Æ new+1 = old 8 10 9 12 11 7 1 3 2 4 5 6 ret R n Æ wp (>,ops) = ? ?

20 20 Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 LOCK=0 Æ new = old LOCK=0 Æ new+1 = new LOCK=1 Æ new+1 = old 8 10 9 12 11 7 1 3 2 4 5 6 ret Track the predicate: new = old

21 21 Step 3: Resume search 1 LOCK=0 2 4 LOCK=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 5 LOCK=0 Æ : new = old 3 LOCK=1 Æ new = old

22 22 Step 3: Resume search 1 LOCK=0 2 3 LOCK=1 Æ new = old 4 5 LOCK=0 Æ : new = old ? 62 LOCK=0 Æ : new = old [>][>] 5 LOCK=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 ret LOCK=0Æ new=old

23 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: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() [>][>] [>][>]

24 24 Step 4: Search Right Branch 1 LOCK=0 [>][>] 2 7 [>][>] 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

25 25 Leaves Covered (Reuse work) 1 LOCK=0 2 7 2 2 2 LOCK=0 Æ … COVERED ! Leaves covered: Avoid repeating search when paths merge 8 10 9 12 11 7 1 3 2 4 5 6 ret

26 26 Different Abstractions 1 2 7 got_lock = 0new = old Different predicates for different parts of state space Local refinement: Preserves work on left tree 8 10 9 12 11 7 1 3 2 4 5 6 ret

27 27 Reachability Tree 1 LOCK=0 2 3 LOCK=1 Æ new = old 4 5 LOCK=0 Æ : new = old ? 62 5 LOCK=1 Æ new=old 6 1 ? ret LOCK=0Æ new=old 8 12 7 10 11 12 11 9 LOCK=0 12 8 2 LOCK=0 Æ got_lock=0 LOCK=1 Æ got_lock!=0 LOCK=0 Æ got_lock=0 ? ?

28 28 Invariants 1 LOCK=0 2 3 LOCK=1 Æ new = old 4 5 LOCK=0 Æ : new = old ? 62 5 LOCK=1 Æ new=old 6 1 ? ret LOCK=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

29 29 Proof Generation 1 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), c jk ) ) Inv (k) These can be formalized as in PCC 1.Inv (1) contains Pre as disjunct 2.Error node not in tree

30 30 Proof Generation II 1 3 2 4 5 6 ret LOCK=0 Æ : new = old Ç LOCK=1 Æ new=old [new==old] [new!=old] Prove : Post ( Inv (i), c ij ) ) 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

31 31 Proof Generation II 1 3 2 4 5 6 ret LOCK=0 Æ : new = old Ç LOCK=1 Æ new=old [new==old] [new!=old] Prove : Post ( Inv (i), c ij ) ) 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

32 32 Lazy abstraction For any system, require: Region representation Boolean operations: [, Å, : “Covering” check: µ post # : Region ! Approx. succ. Region Forward Search pre: Region ! Exact pred. Region Backward counterexample analysis focus : why a trace is infeasible

33 33 BLAST LAZY ABSTRACTION Berkeley Lazy Abstraction Software verification Tool 10K Lines of Ocaml Analyze Linux/Windows Device Drivers CIL (C ! CFA) REGION STRUCTURE BDD Engine (Boolean ops) Simplify (Post # ) Vampyre (focus) Proof Gen (PCC)

34 34 MPR3 CallDriver MPR completion synch not pending returned SKIP2 IPC CallDriver Skip return child status DC Complete request return not Pend PPC prop completion CallDriver N/A no prop completion CallDriver start NP return Pending NP MPR1 MPR completion SKIP2 IPC CallDriver DC Complete request PPC prop completion CallDriver N?A no prop completion CallDriver start P Mark Pending IRP accessible N/A synch SKIP1 CallDriver SKIP1 Skip MPR2 MPR1 NP MPR3 CallDriver not pending returned MPR2 synch From the SLAM project

35 35 Experiments Windows Drivers (IRP Spec – 22 states) ProgramLinesPredicatesTimeProof floppy.c 17386623735 min 17386934421 min60K parport.c 617811935033 min103K mouclass.c 1735257461 min cdaudio.c 17798854523 min156K kbfiltr.c 1213154401 min 1213112810 sec7K

36 36 Experiments : Linux Locking ProgramLinesPredicatesTimeProof ide.c 18131554 sec253 aironet.c 1815217114 min aha152x.c 177362220 sec tlan.c 16505547 min405

37 37 Why Abstract Lazily ? Reach set is very sparse Abstract on-the-fly Only the reachable region Requires very fast post # Exploit Control-Flow Structure Free partitioning of state space Partition preds: different abstractions Refine locally: don ’ t repeat old work

38 38 Problems/Future work Engineering Issues Program analysis Partitioning by partial evaluation Theory of counterexample driven refinement for all linear and branching time logics

39 39 Predicate Abstraction P 1 : x = y P 3 : x  z+1 P 2 : z = t + y P 4 : * u = x Karnaugh Map :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4 Set of states Abstract Set: P 1 P 2 P 4 Ç : P 1 P 2 P 3 P 4 Region Representation: formulas over predicates

40 40 Predicate Abstraction Box: abstract variable valuation BoxCover(S): Set of boxes covering S Theorem prover used to compute BoxCover P 1 : x = y P 3 : x  z+1 P 2 : z = t + y P 4 : * u = x Karnaugh Map :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4

41 41 Post #, Pre pre(S,op) = { s | 9 s ’ 2 S. s ! op s ’ } ( Weakest Precondition ) post(S,op) = { s | 9 s ’ 2 S. s ’ ! op s} ( Strongest Postcondition ) Abstract Operators: post # post(S,op) µ post # (S,op) Concrete Operators: pre Classical Weakest Precondition :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4 S post post(S) post # (S)

42 42 Predicate Discovery Information lost in substitution Keep substitutions explicit Ask a proof of unsatisfiability Pick predicates appearing in proof 2 LOCK=0 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 Æ new+1 = new

43 43 New Predicates from proof of unsatisfiability old’ = new, new’ = old’, new’ = new + 1 Predicate Discovery Weakest Precondition: wp( , x=e) ´  [e/x] Explicit WP: wp( , x=e) ´ 9 x’. x’ = e Æ  [x’/x] LOCK = 0 Æ 9 old’ new’ LOCK’. old’ = new Æ LOCK’=0 Æ new’ = old’ Æ new’ = new’ + 1 2 LOCK=0 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 Æ new+1 = new

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


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

Similar presentations


Ads by Google