11/27/2011 Heap Cloning: Enabling Dynamic Symbolic Execution of Java Programs Saswat Anand Mary Jean Harrold Supported by NSF (CCF-0725202, CCF-0541048) and IBM (Software Quality Innovation Award) Symbolic Execution 35 Databases 30 Systems 25 Verification 20 15 Security 10 Programming Languages 5 Software 0 Engineering 2005 2006 2007 2008 2009 2010 2011 Estimated number of publications related to symbolic execution. The list of papers available at: http://sites.google.com/site/symexbib 1
11/27/2011 Symbolic Execution 35 Databases 30 Systems 25 Goal of this work is to enable correct Verification 20 symbolic execution of real-world Java 15 Security programs with minimal manual effort. 10 Programming Languages 5 Software 0 Engineering 2005 2006 2007 2008 2009 2010 2011 Estimated number of publications related to symbolic execution. The list of papers available at: http://sites.google.com/site/symexbib Outline • Problem • Heap Cloning • Empirical evaluation • Conclusion 2
11/27/2011 Outline • Problem • Heap Cloning • Empirical evaluation • Conclusion Symbolic Execution of Real-World Programs P’ not symbolically executed because: To be P’ 1. P’ uses difficult -to- symbolically executed handle Java features Not to be such as native methods. symbolically 2. symbolic execution of P’ P executed is mostly unnecessary. Program 3
11/27/2011 Symbolic Execution with User-specified Models Replace P’ with user-specified To be models P M P M symbolically executed Impractical! Requires significant P manual effort. Program Dynamic Symbolic Execution Symbolic execution P: to be symbolically executed P’: not to be symbolically executed Concrete execution Call/return P’ No manual effort to write models P Program 4
11/27/2011 Example class A { void negate() { int f; this.f = -this.f; A(int x) { } this.f = x; Java version of } native method negate native void negate(); } Example class A { int f; Task: A(int x) { Perform dynamic symbolic this.f = x; execution along the path (1-2- } 3-4-5-7) that program takes for concrete input -10. native void negate(); Requirement: void main() { Native method negate() not 1 x = read(); 2 m = new A(x); to be symbolically executed 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) 6 error(); 7 exit(); } } 5
11/27/2011 Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) 6 error(); Continued on 7 exit(); next slide -10, X 0 x PC: true state before: m = new A(x) Dynamic Symbolic Execution 1 x = read(); Path Constraint (PC) of a 2 m = new A(x); 3 if(m.f < 0) path is a constraint of input 4 m.negate(); values. 5 if(m.f < 0) 6 error(); Continued on 7 exit(); next slide If PC is unsatisfiable, the path is infeasible. -10, X 0 If PC is satisfiable, any x solution of PC is a program PC: true input that takes the corresponding program path. state before: m = new A(x) 6
11/27/2011 Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) 6 error(); Continued on 7 exit(); next slide f -10, X 0 A -10, X 0 x m x PC: true PC: true state before: m = new A(x) state before: if(m.f < 0) Differences between two successive states are shown in Red . Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) 6 error(); Continued on 7 exit(); next slide f f -10, X 0 -10, X 0 A -10, X 0 A x m x m x PC: true PC: X 0 < 0 PC: true state before: m = new A(x) state before: if(m.f < 0) state before: m.negate() Differences between two successive states are shown in Red . 7
11/27/2011 Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) Continued 6 error(); from prev. 7 exit(); slide Without model of negate native method f -10, X 0 A m x PC: X 0 < 0 state before: m.negate() Differences between two successive states are shown in Red . Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) 4 m.negate(); 5 if(m.f < 0) Continued 6 error(); from prev. 7 exit(); slide Without model of negate native method f f -10, X 0 10, X 0 -10, X 0 A A m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . 8
11/27/2011 Dynamic Symbolic Execution 1 x = read(); Concrete value of the field 2 m = new A(x); changed from -10 to 10. But, 3 if(m.f < 0) 4 m.negate(); symbolic value X 0 did not 5 if(m.f < 0) change. Continued 6 error(); from prev. 7 exit(); slide Without model of negate native method f f -10, X 0 10, X 0 -10, X 0 A A m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) UNSAT Solve PC: X 0 < 0 & X 0 >= 0 4 m.negate(); 5 if(m.f < 0) Continued 6 error(); from prev. 7 exit(); slide Without model of negate native method -10, X 0 10, X 0 -10, X 0 A A m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . 9
11/27/2011 Dynamic Symbolic Execution 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) UNSAT Solve PC: X 0 < 0 & X 0 >= 0 4 m.negate(); 5 if(m.f < 0) Continued 6 error(); from prev. 7 exit(); Meaning: there is no slide Without model of negate native method input that takes the path 1-2-3-4-5-7 -10, X 0 10, X 0 -10, X 0 A A Incorrect! m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . Dynamic Symbolic Execution with Models 1 x = read(); void negate() { 2 m = new A(x); this.f = -this.f; 3 if(m.f < 0) } 4 m.negate(); User-specified 5 if(m.f < 0) model of negate Continued 6 error(); from prev. 7 exit(); slide -10, X 0 A m x PC: X 0 < 0 state before: m.negate() Differences between two successive states are shown in Red . 10
11/27/2011 Dynamic Symbolic Execution with Models 1 x = read(); void negate() { 2 m = new A(x); this.f = -this.f; 3 if(m.f < 0) } 4 m.negate(); User-specified 5 if(m.f < 0) model of negate Continued 6 error(); from prev. 7 exit(); slide With model of negate native method -10, X 0 10, -X 0 -10, X 0 A A m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . Dynamic Symbolic Execution with Models 1 x = read(); 2 m = new A(x); 3 if(m.f < 0) X 0 = -1 Solve PC: X 0 < 0 & -X 0 >= 0 4 m.negate(); 5 if(m.f < 0) Continued 6 error(); from prev. 7 exit(); slide With model of negate native method -10, X 0 10, -X 0 -10, X 0 A A m x m x PC: X 0 < 0 PC: X 0 < 0 state before: m.negate() states before: if(m.f < 0) Differences between two successive states are shown in Red . 11
11/27/2011 But, Models Not Always Needed for Soundness! void negate() { this.f = -this.f; } Modified example Original example 1 x = read(); 1 x = read(); 2 m = new A(x); 2 m = new A(x); 3 if(m.f < 0) 3 if(m.f < 0) 4 m.negate(); 4 m.negate(); 5 if(m.f < 0) 5 if(x < 0) 6 error(); 6 error(); 7 exit(); 7 exit(); But, Models Not Always Needed for Soundness! void negate() { Stmt at line 5 uses the Stmt at line 5 does not Stmt at line 5 uses the Stmt at line 5 does not this.f = -this.f; value defined inside use the value defined value defined inside use the value defined } negate method. inside negate method. inside negate method. negate method . Modified example Original example Thus, negate Thus, negate does not introduces imprecision. introduce imprecision. 1 x = read(); 1 x = read(); Thus, model for negate 2 m = new A(x); 2 m = new A(x); Thus, no need for model for negate . is needed. 3 if(m.f < 0) 3 if(m.f < 0) 4 m.negate(); 4 m.negate(); 5 if(m.f < 0) 5 if(x < 0) 6 error(); 6 error(); 7 exit(); 7 exit(); 12
11/27/2011 Goal and Approach Goal: Identify where imprecision is introduced and report to user. User then provides models for only a subset methods in P’ to eliminate imprecision. Approach : 1. Transform the program using Heap Cloning. 2. Perform dynamic symbolic execution of the transformed program without any models 3. Detect and report where imprecision might be introduced. Outline • Problem • Heap Cloning • Empirical evaluation • Conclusion 13
11/27/2011 Heap Cloning Heap Cloning Original Transformed Program P Program P T Transformation 1. Symbolic execution of P T generates same results as symbolic execution of P. 2. However, if imprecision is introduced during symbolic execution of P T , it can be detected and reported to user. Heap Cloning For every class A, Heap class HC.java.lang.Object { … Cloning generates HC.A. } For each field (method) class HC.A extends of A, HC.A has a HC.java.lang.Object { corresponding field (method). If class A extends class HC.A m = new HC.A(); B, HC.A extends HC.B Almost all references to } A are changed to HC.A 14
Recommend
More recommend