Automatic Abstraction in SMT-Based Unbounded Software Model Checking Anvesh Komuravelli Carnegie Mellon University Joint work with Arie Gurfinkel, Sagar Chaki and Edmund Clarke Spacer © Anvesh Komuravelli The Problem Safe + Proof Program P Automatic analysis for assertion failures + Assertions Is it empty? Unsafe + Counterexample Unknown + Partial Proof reach(P) error(P) Software Model Checking Spacer © Anvesh Komuravelli 1 Over-approximation Driven (OD) error(P) reach(P) Spacer © Anvesh Komuravelli 2 Over-approximation driven (OD) reach(P) error(P) Spacer © Anvesh Komuravelli 3 Over-approximation driven (OD) Key Idea CEGAR based on Predicate Abstraction Symbolic Method BDDs for fixed point computation, SMT for new predicates Tools SLAM, BLAST, SDV, etc. Spacer © Anvesh Komuravelli 4 Under-approximation Driven (UD) reach(P) error(P) Spacer © Anvesh Komuravelli 5 Under-approximation driven (UD) reach(P) error(P) Spacer © Anvesh Komuravelli 6 Under-approximation driven (UD) Key Idea BMC based Approach Symbolic SMT Method Tools IMPACT, UFO, etc. Spacer © Anvesh Komuravelli 7 Key Recent Advancements 2003 Interpolation for Hardware Model Checking McMillan 2006 IMPACT (Path Interpolants) McMillan 2009 Path Interpolants for Hardware Model Checking Grumberg et al. 2010 IC3 (Different way of computing Interpolants, Hardware) Bradley 2011 WOLVERINE (Bit-level Implementation of IMPACT) Kroening et al. 2012 UFO (DAG Interpolation method, Predicate Abstraction + Interpolation) Gurfinkel et al. 2012 VINTA (Abstract Interpretation + Interpolation) Gurfinkel et al. 2011 FunFrog (Interprocedural) Sharygina et al. 2012 μZ (Horn clause solver based on GPDR) Bjorner et al. 2012 Duality (Horn clause solver based on Interpolation) McMillan, Rybalchenko 2012 WHALE (Interprocedural) Gurfinkel et al. Spacer © Anvesh Komuravelli 8 Our Strategy error(P) reach(P) Under-approx. Abstract Under-approx. Spacer © Anvesh Komuravelli 9 Our Strategy reach(P) error(P) Under-approx. Abstract Under-approx. Refine Spacer © Anvesh Komuravelli 10 Our Strategy reach(P) error(P) Under-approx. Abstract Under-approx. Refine Abstract Spacer © Anvesh Komuravelli 11 Our Strategy reach(P) error(P) And so on … Spacer © Anvesh Komuravelli 12 Our Strategy reach(P) is covered reach(P) error(P) Abstractions guide the SMT solver to look for general proofs Spacer © Anvesh Komuravelli 13 It’s based on UD Under-approximations … A b s t r a c t … … … Spacer © Anvesh Komuravelli 14 It’s based on UD Under-approximations need not be monotonic … A b s t r a c t … … … Spacer © Anvesh Komuravelli 15 Spacer is based on UD Under-approximations … … A b s t r a c t … non-trivial abstraction … Spacer © Anvesh Komuravelli 16 Spacer Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Refine CEGAR No Feasible? Counterexample Yes Yes Spacer © Anvesh Komuravelli 17 Why Abstraction? x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (0 ≤ y) only way to fail the assertion Spacer © Anvesh Komuravelli 18 UD Reasoning y ≤ 100x x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (0 ≤ y) 1st Iteration: w = 0, z = 0 Spacer © Anvesh Komuravelli 19 UD Reasoning y ≤ 100x x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (0 ≤ y) 2nd Iteration: w = 1, z =10 Spacer © Anvesh Komuravelli 20 UD Reasoning y ≤ 100x x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (0 ≤ y) 3rd Iteration: w = 2, z = 20 And so on… Spacer © Anvesh Komuravelli 21 But … x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (0 ≤ y) The value ‘1’ doesn’t matter! Spacer © Anvesh Komuravelli 22 But … x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = *; w += t; z += 10t; } assert (0 ≤ y) Spacer © Anvesh Komuravelli 23 UD Reasoning on the Abstraction y ≤ 100x x = y = z = w = 0; while (*) { x = *; y = *; assume (0 ≤ y ≤ 100x); if (y > 10w && z ≥ 100x) { y = −y; } t = *; w += t; z += 10t; } assert (0 ≤ y) All Iterations 2nd Iteration Redundant w = t, z = 10t Resolve t away z = 10w Spacer © Anvesh Komuravelli 24 Original Example x = y = z = w = 0; while (*) { if (*) {x++; y += 100;} else if (*) if (x ≥ 4) {x++; y++;} else if (y > 10w && z ≥ 100x) { y = −y; } t = 1; w += t; z += 10t; } assert (!(x ≥ 4 && y ≤ 2)) μZ (SMT-Based Model Checker, part of Z3) Cannot solve in an hour Solves an abstraction in < 1 sec. t = *; Spacer (our tool) Finds a proof in a min. Source: Automatically Refining Abstract Interpretations, Gulavani, Chakraborty, Nori and Rajamani, TACAS ‘08. Spacer © Anvesh Komuravelli 25 What’s the magic? Focused Proofs Abstractions guide the SMT solver to look for certain kind of proofs Avoid proofs specific to an under-approximation How to obtain abstractions? From proofs of under-approximations! (Proof-Based Abstraction) Hope: What’s sufficient for the under-approximation is sufficient in general Downside: If abstraction is too coarse, need to refine (CEGAR) Spacer © Anvesh Komuravelli 26 Spacer Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Refine CEGAR No Feasible? Counterexample Yes Yes Spacer © Anvesh Komuravelli 27 Schematic Example init_stmt; c = 0; Add Counters while (*) { // invar_1, invar_2 // invar_3, invar_4 assume (c < k1); if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = e6; c += 1; Loop Invariants } assert (safe); Under-approximate Solve Spacer © Anvesh Komuravelli 28 Schematic Example Treat as guessed unbounded invariants. Essentially like Houdini [FL’01]. Specific to under-approx. Extract Unbounded Invariants Strengthen with Invariants init_stmt; c = 0; assume (invar_1, invar_2); while (*) { // invar_1, invar_2 // invar_3, invar_4 assume (c < k1); if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = e6; c += 1; assume (invar_1, invar_2); } [FL’01] Houdini, an annotation assistant for ESC/Java, C. Flanagan and K.R.M. Leino, 2001 Unbounded! assert (safe); Under-approximate Solve Feasible? Spacer © Anvesh Komuravelli 29 Schematic Example Does not prove the assertion init_stmt; c = 0; assume (invar_1, invar_2); while (*) { // invar_1, invar_2 if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = e6; c += 1; assume (invar_1, invar_2); } assert (safe); Under-approximate Solve Feasible? NO Spacer © Anvesh Komuravelli 30 Schematic Example init_stmt; c = 0; assume (invar_1, invar_2); while (*) { // invar_1, invar_2 // invar_3, invar_4 assume (c < k1); if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = e6; c += 1; assume (invar_1, invar_2); } Redundant for the proof assert (safe); Under-approximate Solve Feasible? NO Abstract Spacer © Anvesh Komuravelli 31 Schematic Example init_stmt; c = 0; assume (invar_1, invar_2); while (*) { // invar_1, invar_2 // invar_3, invar_4 assume (c < k1); if (*) { v1 = e1; v2 = *; } else { v3 = e3; v4 = *; } v5 = e5; v6 = *; c += 1; assume (invar_1, invar_2); } Proof-Based Abstraction assert (safe); Under-approximate Solve Feasible? NO Abstract Spacer © Anvesh Komuravelli 32 Schematic Example init_stmt; c = 0; assume (invar_1, invar_2); while (*) { Abstract Counterexample! assume (c < k2); if (*) { v1 = e1; v2 = *; } else { v3 = e3; v4 = *; } v5 = e5; v6 = *; c += 1; assume (invar_1, invar_2); Concrete control path is infeasible k2 > k1 Concretize } assert (safe); Under-approximate Solve Feasible? NO Refine Spacer © Anvesh Komuravelli 33 Schematic Example init_stmt; c = 0; assume (invar_1, invar_2); while (*) { assume (c < k2); if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = *; c += 1; assume (invar_1, invar_2); CEGAR } assert (safe); Under-approximate Solve Feasible? NO Refine Spacer © Anvesh Komuravelli 34 Schematic Example Invariants init_stmt; c = 0; assume (invar_1, invar_2); while (*) { // invar_5 // invar_6 assume (c < k2); if (*) { v1 = e1; v2 = e2; } else { v3 = e3; v4 = e4; } v5 = e5; v6 = *; c += 1; assume (invar_1, invar_2); } Unbounded assert (safe); Under-approximate Solve Feasible? YES Spacer © Anvesh Komuravelli 35 Spacer Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Refine CEGAR No Feasible? Counterexample Yes Yes Spacer © Anvesh Komuravelli 36 Detailed Example x = y = z = w = 0; if (nd ()) {x++; y += 100;} else if (nd () && x ≥ 4) {x++; y++;} else if (y > 10w && z ≥ 100x) {y = −y;} while (*) { else assume (0); C-like if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; non-deterministic choice (e.g. as in Promela) } assert (!(x ≥ 4 && y ≤ 2)); Spacer © Anvesh Komuravelli 37 Detailed Example x = y = z = w = 0; c = 0; Add Counters while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; c += 1; Loop Invariants } assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Spacer © Anvesh Komuravelli 38 Detailed Example x = y = z = w = 0; c = 0; Inductive Invariant Safe while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; c += 1; } assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Spacer © Anvesh Komuravelli 39 Detailed Example Specific to under-approx. Extract Unbounded Invariants Strengthen with Invariants x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } Preserved! Depend on counter assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? Spacer © Anvesh Komuravelli 40 Detailed Example Does not prove the assertion x = y = z c = 0; assume (y while (*) // (y = w = 0; > 10w => z < 100x, z ≤ 100x); { > 10w) => (z < 100x), z ≤ 100x, if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? NO Spacer © Anvesh Komuravelli 41 Detailed Example x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w++; z += 10; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } Redundant assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? NO Abstract Spacer © Anvesh Komuravelli 42 Detailed Example Fails x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y = *; :: (x ≥ 4) -> x++; y = *; :: (y > 10w && z ≥ 100x) -> y = *; fi w = *; z = *; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } Enlarge error assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? NO Abstract Spacer © Anvesh Komuravelli 43 Detailed Example x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { // (y > 10w) => (z < 100x), z ≤ 100x, // x ≤ 2, c ≤ 0 => x ≤ 0, c ≤ 1 => x ≤ 1 assume (c < 2); if :: x++; y = *; :: (x ≥ 4) -> x++; y = *; :: (y > 10w && z ≥ 100x) -> y = *; fi w = *; z = *; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } assert (!(x ≥ 4)); Under-approximate Solve Feasible? NO Abstract Spacer © Anvesh Komuravelli 44 Detailed Example x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { Counterexample! assume (c < 4); if :: x++; y = *; :: (x ≥ 4) -> x++; y = *; :: (y > 10w && z ≥ 100x) -> y = *; fi w = *; z = *; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); Increment x to 4 Choose y arbitrarily Concrete control path is infeasible Concretize } assert (!(x ≥ 4)); Under-approximate Solve Feasible? NO Refine Spacer © Anvesh Komuravelli 45 Detailed Example x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { assume (c < 4); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w = *; z = *; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? NO Refine Spacer © Anvesh Komuravelli 46 Detailed Example Inductive Invariant Safe x = y = z = w = 0; c = 0; assume (y > 10w => z < 100x, z ≤ 100x); while (*) { // (y > 10w) => (z < 100x), z ≤ 100x // y > 0, (x > 0) => (y ≥ 100) assume (c < 4); if :: x++; y += 100; :: (x ≥ 4) -> x++; y++; :: (y > 10w && z ≥ 100x) -> y = −y; fi w = *; z = *; c += 1; assume (y > 10w => z < 100x, z ≤ 100x); } Unbounded assert (!(x ≥ 4 && y ≤ 2)); Under-approximate Solve Feasible? YES Spacer © Anvesh Komuravelli 47 Implementation Details – Unbounded Invariants Pre-Lemmas Goal Concrete Counters Find maximal Post-Lemmas such that Spacer © Anvesh Komuravelli 48 Implementation Details – Unbounded Invariants SAT? UNSAT SAT with true Repeat until fixed point Spacer © Anvesh Komuravelli 49 Implementation Details – Unbounded Invariants Introduce Assumption variables Fixed point Iteration: Maximal subset of true post-lemmas Minimal number of bi’s to be set to false Spacer © Anvesh Komuravelli 50 Implementation Details – Unbounded Invariants disabled disabled Iteration 1 ✔ ✗ Iteration 2 ✗ Spacer © Anvesh Komuravelli 51 Implementation Details – Abstraction Introduce Assumption variables Spacer © Anvesh Komuravelli 52 Implementation Details – Abstraction Are all lemmas necessary? Spacer © Anvesh Komuravelli 53 Implementation Details – Abstraction Introduce Assumption variables for lemmas Spacer © Anvesh Komuravelli 54 Spacer Tool Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Refine CEGAR No Feasible? Counterexample Yes Yes Spacer © Anvesh Komuravelli 55 Spacer Tool Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Refine CEGAR No Feasible? Counterexample Yes Yes μZ Horn-Clause Solver (part of Z3) Spacer © Anvesh Komuravelli 56 Spacer Tool Program UnderApproximate Abstract No Proof-Based Abstraction Feasible? Safety Proof Check Safety Horn-Clause Refine Encoding CEGAR No Feasible? Counterexample Yes Yes μZ Horn-Clause Solver (part of Z3) Spacer © Anvesh Komuravelli 57 Spacer Tool C Program Preprocessing Horn Clause Encoding UFO Frontend (based on LLVM) Simplification, Large Block Encoding, etc. Implemented using UFO Frontend Spacer © Anvesh Komuravelli 58 Results on SV-COMP’13 Benchmarks UNSAFE Benchmarks Spacer (secs) 150 Abstraction did not help for UNSAFE 100 ALSO, not a challenging pool of benchmarks 50 0 0 50 100 μZ (secs) 150 Spacer © Anvesh Komuravelli 59 Results on SV-COMP’13 Benchmarks SAFE Benchmarks 900 800 Spacer (secs) 700 600 500 400 300 200 100 0 0 100 200 300 400 500 600 700 800 900 μZ (secs) Spacer © Anvesh Komuravelli 60 Results on SV-COMP’13 Benchmarks SAFE Benchmarks 900 800 Spacer (secs) 700 600 500 ~1 min. Not very meaningful to compare 400 300 200 100 0 0 100 200 300 400 500 600 700 800 900 μZ (secs) Spacer © Anvesh Komuravelli 61 Results on SV-COMP’13 Benchmarks SAFE Benchmarks 900 800 Spacer (secs) 700 600 500 < 5 min. Mixed Results 400 300 200 100 0 0 100 200 300 400 500 600 700 800 900 μZ (secs) Spacer © Anvesh Komuravelli 62 Results on SV-COMP’13 Benchmarks SAFE Benchmarks 900 Advantage! 800 Spacer (secs) 700 600 500 400 300 200 100 0 0 100 200 300 400 500 600 700 800 900 μZ (secs) Spacer © Anvesh Komuravelli 63 Results on SV-COMP’13 Benchmarks SAFE Benchmarks 900 Advantage! 800 Spacer (secs) 700 600 Time-out 500 Mem-out 400 300 200 100 0 0 100 200 300 400 500 600 700 800 900 μZ (secs) Spacer © Anvesh Komuravelli 64 Conclusion Focused Proofs Abstractions guide the SMT solver to look for certain kind of proofs Avoid proofs specific to an under-approximation How to obtain abstractions? From proofs of under-approximations! (Proof-Based Abstraction) Hope: What’s sufficient for the under-approximation is sufficient in general Downside: If abstraction is too coarse, need to refine (CEGAR) Contributions A framework for automated abstraction in SMT-based Software Model Checking Implementation using an existing SMT-based model checker with practical advantage Spacer © Anvesh Komuravelli 65 Conclusion (contd…) Why does PBA work? Post-pruning of Proofs during Abstraction (Local vs. Global Proofs) Non-monotonic abstractions Major role of invariants (exploit the generality of proofs of under-approximations Visit spacer.bitbucket.org to download tool and detailed slides! Spacer © Anvesh Komuravelli 66 On-going and Future Work Observation: Fixed granularity of abstraction – at the program level Observation: Restricted space of abstractions Questions: When/How to abstract/refine? Observation: Proofs too dependent on counter constraints (i.e. underapprox.) Question: How to use counters only when needed? In general, how to minimize the use of a given set of assumptions? Observation: Abstraction is done offline, after obtaining a proof of an underapproximation. Question: How does an on-the-fly abstraction work? When each transition is treated as a recursion-free procedure, it is similar to summarizing procedures on-the-fly. Also, how to handle recursion? Spacer © Anvesh Komuravelli 67 Read our CAV’13 paper for details… Questions? Spacer © Anvesh Komuravelli 68 Extra Slides Spacer © Anvesh Komuravelli 69 SMT-Based Model Checking init Discharge Verification Condition on SMT solver Possibility 1 : UNSAFE Possibility 2 : SAFE Path Interpolants (McMillan ‘06) error CFG Loop-Free Unrolling Spacer © Anvesh Komuravelli 70 SMT-Based Model Checking init Discharge Verification Condition on SMT solver Possibility 1 : UNSAFE Possibility 2 : SAFE DAG Interpolants [AGC’12] error Continue Until Convergence CFG Further Unrolling [AGC’12] : From Under-approximations to Overapproximations and Back, Albarghouthi, Gurfinkel and Chechik, TACAS ‘12 Spacer © Anvesh Komuravelli 71