PLDI’2005Page 1June 2005 DART: Directed Automated Random Testing Patrice Godefroid Nils Klarlund Koushik Sen Bell Labs Bell Labs UIUC.

Slides:



Advertisements
Similar presentations
Cristian Cadar, Peter Boonstoppel, Dawson Engler RWset: Attacking Path Explosion in Constraint-Based Test Generation TACAS 2008, Budapest, Hungary ETAPS.
Advertisements

1 Symbolic Execution Kevin Wallace, CSE
Masahiro Fujita Yoshihisa Kojima University of Tokyo May 2, 2008
Symbolic Execution with Mixed Concrete-Symbolic Solving
PLDI’2005Page 1June 2005 Example (C code) int double(int x) { return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10)
1 Chao Wang, Yu Yang*, Aarti Gupta, and Ganesh Gopalakrishnan* NEC Laboratories America, Princeton, NJ * University of Utah, Salt Lake City, UT Dynamic.
White Box and Black Box Testing Tor Stålhane. What is White Box testing White box testing is testing where we use the info available from the code of.
Finding bugs: Analysis Techniques & Tools Comparison of Program Analysis Techniques CS161 Computer Security Cho, Chia Yuan.
A Randomized Dynamic Program Analysis for Detecting Real Deadlocks Koushik Sen CS 265.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
Symbolic execution © Marcelo d’Amorim 2010.
Annoucements  Next labs 9 and 10 are paired for everyone. So don’t miss the lab.  There is a review session for the quiz on Monday, November 4, at 8:00.
David Brumley, Pongsin Poosankam, Dawn Song and Jiang Zheng Presented by Nimrod Partush.
Hybrid Concolic Testing Rupak Majumdar Koushik Sen UC Los Angeles UC Berkeley.
Dynamic Symbolic Execution CS 8803 FPL Oct 31, 2012 (Slides adapted from Koushik Sen) 1.
Theoretical Program Checking Greg Bronevetsky. Background The field of Program Checking is about 13 years old. Pioneered by Manuel Blum, Hal Wasserman,
(Quickly) Testing the Tester via Path Coverage Alex Groce Oregon State University (formerly NASA/JPL Laboratory for Reliable Software)
CSE503: SOFTWARE ENGINEERING SYMBOLIC TESTING, AUTOMATED TEST GENERATION … AND MORE! David Notkin Spring 2011.
Precise Inter-procedural Analysis Sumit Gulwani George C. Necula using Random Interpretation presented by Kian Win Ong UC Berkeley.
DART Directed Automated Random Testing Patrice Godefroid, Nils Klarlund, and Koushik Sen Syed Nabeel.
Evaluation of DART DART: Directed Automated Random Testing Godefroid, Klarlund, Sen.
1 Today More on random testing + symbolic constraint solving (“concolic” testing) Using summaries to explore fewer paths (SMART) While preserving level.
1 Software Testing and Quality Assurance Lecture 5 - Software Testing Techniques.
State coverage: an empirical analysis based on a user study Dries Vanoverberghe, Emma Eyckmans, and Frank Piessens.
1 Functional Testing Motivation Example Basic Methods Timing: 30 minutes.
CS527: (Advanced) Topics in Software Engineering Overview of Software Quality Assurance Tao Xie ©D. Marinov, T. Xie.
Automating Software Testing Using Program Analysis -Patrice Godefroid, Peli de Halleux, Aditya V. Nori, Sriram K. Rajamani,Wolfram Schulte, and Nikolai.
System/Software Testing
DART: Directed Automated Random Testing Koushik Sen University of Illinois Urbana-Champaign Joint work with Patrice Godefroid and Nils Klarlund.
TESTING.
CUTE: A Concolic Unit Testing Engine for C Technical Report Koushik SenDarko MarinovGul Agha University of Illinois Urbana-Champaign.
INT-Evry (Masters IT– Soft Eng)IntegrationTesting.1 (OO) Integration Testing What: Integration testing is a phase of software testing in which.
1 Principles of Computer Science I Prof. Nadeem Abdul Hamid CSC 120 – Fall 2005 Lecture Unit 10 - Testing.
Automated Whitebox Fuzz Testing (NDSS 2008) Presented by: Edmund Warner University of Central Florida April 7, 2011 David Molnar UC Berkeley
Automated Whitebox Fuzz Testing Network and Distributed System Security (NDSS) 2008 by Patrice Godefroid, ‏Michael Y. Levin, and ‏David Molnar Present.
Testing and Debugging Version 1.0. All kinds of things can go wrong when you are developing a program. The compiler discovers syntax errors in your code.
COMP 121 Week 1: Testing and Debugging. Testing Program testing can be used to show the presence of bugs, but never to show their absence! ~ Edsger Dijkstra.
CSV 889: Concurrent Software Verification Subodh Sharma Indian Institute of Technology Delhi Symbolic Execution.
Xusheng Xiao North Carolina State University CSC 720 Project Presentation 1.
jFuzz – Java based Whitebox Fuzzing
Finding Errors in.NET with Feedback-Directed Random Testing Carlos Pacheco (MIT) Shuvendu Lahiri (Microsoft) Thomas Ball (Microsoft) July 22, 2008.
Design - programming Cmpe 450 Fall Dynamic Analysis Software quality Design carefully from the start Simple and clean Fewer errors Finding errors.
Software Engineering 2004 Jyrki Nummenmaa 1 BACKGROUND There is no way to generally test programs exhaustively (that is, going through all execution.
CSV 889: Concurrent Software Verification Subodh Sharma Indian Institute of Technology Delhi Scalable Symbolic Execution: KLEE.
Symbolic and Concolic Execution of Programs Information Security, CS 526 Omar Chowdhury 10/7/2015Information Security, CS 5261.
CS265: Dynamic Partial Order Reduction Koushik Sen UC Berkeley.
Software Quality Assurance and Testing Fazal Rehman Shamil.
CUTE: A Concolic Unit Testing Engine for C Koushik SenDarko MarinovGul Agha University of Illinois Urbana-Champaign.
Dynamic Testing.
Testing and Debugging. Testing Fundamentals  Test as you develop Easier to find bugs early rather than later Prototyping helps identify problems early.
/ PSWLAB Evidence-Based Analysis and Inferring Preconditions for Bug Detection By D. Brand, M. Buss, V. C. Sreedhar published in ICSM 2007.
Lazy Annotation for Program Testing and Verification (Supplementary Materials) Speaker: Chen-Hsuan Adonis Lin Advisor: Jie-Hong Roland Jiang December 3,
Dynamic Symbolic Execution (aka, directed automated random testing, aka concolic execution) Slides by Koushik Sen.
MOPS: an Infrastructure for Examining Security Properties of Software Authors Hao Chen and David Wagner Appears in ACM Conference on Computer and Communications.
Random Test Generation of Unit Tests: Randoop Experience
Week 6 MondayTuesdayWednesdayThursdayFriday Testing III Reading due Group meetings Testing IVSection ZFR due ZFR demos Progress report due Readings out.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION SYMBOLIC TESTING Autumn 2011.
SOFTWARE TESTING LECTURE 9. OBSERVATIONS ABOUT TESTING “ Testing is the process of executing a program with the intention of finding errors. ” – Myers.
Testing Tutorial 7.
Software Testing.
Chapter 8 – Software Testing
runtime verification Brief Overview Grigore Rosu
Types of Testing Visit to more Learning Resources.
Presented by Mahadevan Vasudevan + Microsoft , *UC-Berkeley
All You Ever Wanted to Know About Dynamic Taint Analysis & Forward Symbolic Execution (but might have been afraid to ask) Edward J. Schwartz, Thanassis.
Elided to examples only
Automatic Test Generation SymCrete
Example (C code) int double(int x) { return 2 * x; }
CUTE: A Concolic Unit Testing Engine for C
The Zoo of Software Security Techniques
Presentation transcript:

PLDI’2005Page 1June 2005 DART: Directed Automated Random Testing Patrice Godefroid Nils Klarlund Koushik Sen Bell Labs Bell Labs UIUC

PLDI’2005Page 2June 2005 Motivation Software testing: “usually accounts for 50% of software development cost” –“Software failures cost $60 billion annually in the US alone” [Source: “The economic impacts of inadequate infrastructure for software testing”, NIST, May 2002] Unit testing: applies to individual software components –Goal: “white-box” testing for corner cases, 100% code coverage –Unit testing is usually done by developers (not testers) Problem: in practice, unit testing is rarely done properly –Testing in isolation with manually-written test harness/driver code is too expensive, testing infrastructure for system testing is inadequate –Developers are busy, (“black-box”) testing will be done later by testers… –Bottom-line: many bugs that should have been caught during unit testing remain undetected until field deployment (corner cases where severe reliability bugs hide) Idea: help automate unit testing by eliminating/reducing the need for writing manually test driver and harness code ! DART

PLDI’2005Page 3June 2005 DART: Directed Automated Random Testing 1. Automated extraction of program interface from source code 2.Generation of test driver for random testing through the interface 3.Dynamic test generation to direct executions along alternative program paths Together: (1)+(2)+(3) = DART DART can detect program crashes and assertion violations. Any program that compiles can be run and tested this way: No need to write any test driver or harness code! (Pre- and post-conditions can be added to generated test-driver)

PLDI’2005Page 4June 2005 Example (C code) int double(int x) { return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } (1) Interface extraction: parameters of toplevel function external variables return values of external functions main(){ int tmp1 = randomInt(); int tmp2 = randomInt(); test_me(tmp1,tmp2); } (2) Generation of test driver for random testing: Closed (self-executable) program that can be run Problem: probability of reaching abort() is extremely low!

PLDI’2005Page 5June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint x = 36, y = 99 create symbolic variables x, y

PLDI’2005Page 6June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 36, y = 99, z = 72 z = 2 * x

PLDI’2005Page 7June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 36, y = 99, z = 72 z = 2 * x 2 * x != y Solve: 2 * x == y Solution: x = 1, y = 2

PLDI’2005Page 8June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint x = 1, y = 2 create symbolic variables x, y

PLDI’2005Page 9June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 1, y = 2, z = 2 z = 2 * x

PLDI’2005Page 10June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 1, y = 2, z = 2 z = 2 * x 2 * x == y

PLDI’2005Page 11June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y 2 * x == y x = 1, y = 2, z = 2 z = 2 * x y != x + 10 Solve: (2 * x == y) Æ (y == x +10) Solution: x = 10, y = 20

PLDI’2005Page 12June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y != x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint x = 10, y = 20 create symbolic variables x, y

PLDI’2005Page 13June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 10, y = 20, z = 20 z = 2 * x

PLDI’2005Page 14June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y x = 10, y = 20, z = 20 z = 2 * x 2 * x == y

PLDI’2005Page 15June 2005 DART Step (3): Directed Search main(){ int t1 = randomInt(); int t2 = randomInt(); test_me(t1,t2); } int double(int x) {return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10) abort(); /* error */ } Concrete Execution Symbolic Execution Path Constraint create symbolic variables x, y 2 * x == y y == x +10 z = 2 * x x = 10, y = 20, z = 20 Program Error

PLDI’2005Page 16June 2005 Directed Search: Summary Dynamic test generation to direct executions along alternative program paths –collect symbolic constraints at branch points (whenever possible) –negate one constraint at a branch point to take other branch (say b) –call constraint solver with new path constraint to generate new test inputs –next execution driven by these new test inputs to take alternative branch b –check with dynamic instrumentation that branch b is indeed taken Repeat this process until all execution paths are covered –May never terminate! Significantly improves code coverage vs. pure random testing

PLDI’2005Page 17June 2005 Novelty: Simultaneous Concrete & Symbolic Executions void foo(int x,int y){ int z = x*x*x; /* could be z = h(x) */ if (z == y) { abort(); /* error */ } Assume we can reason about linear constraints only Initially x = 3 and y = 7 (randomly generated) Concrete z = 27, but symbolic z = x*x*x –Cannot handle symbolic value of z! –Stuck?

PLDI’2005Page 18June 2005 Novelty: Simultaneous Concrete & Symbolic Executions void foo(int x,int y){ int z = x*x*x; /* could be z = h(x) */ if (z == y) { abort(); /* error */ } Assume we can reason about linear constraints only Initially x = 3 and y = 7 (randomly generated) Concrete z = 27, but symbolic z = x*x*x –Cannot handle symbolic value of z! –Stuck? –NO! Use concrete value z = 27 and proceed… Take else branch with constraint 27 != y Solve 27 = y to take then branch Execute next run with x = 3 and y = 27 DART finds the error! Replace symbolic expression by concrete value when symbolic expression becomes unmanageable (e.g. non-linear) NOTE: whenever symbolic execution is stuck, static analysis becomes imprecise!

PLDI’2005Page 19June 2005 Comparison with Static Analysis 1 foobar(int x, int y){ 2 if (x*x*x > 0){ 3 if (x>0 && y==10){ 4 abort(); /* error */ 5 } 6 } else { 7 if (x>0 && y==20){ 8 abort(); /* error */ 9 } 10 } 11 } Symbolic execution is stuck at line 2… Static analysis tools will conclude that both aborts may be reachable –“Sound” tools will report both, and thus one false alarm –“Unsound” tools will report “no bug found”, and miss a bug Static-analysis-based test generation techniques are also helpless here… In contrast, DART finds the only error (line 4) with high probability Unlike static analysis, all bugs reported by DART are guaranteed to be sound

PLDI’2005Page 20June 2005 Other Advantages of Dynamic Analysis 1 struct foo { int i; char c; } 2 3 bar (struct foo *a) { 4 if (a->c == 0) { 5 *((char *)a + sizeof(int)) = 1; 6 if (a->c != 0) { 7 abort(); 8 } 9 } 10 } Dealing with dynamic data is easier with concrete executions Due to limitations of alias analysis, static analysis tools cannot determine whether “a->c” has been rewritten –“the abort may be reachable” In contrast, DART finds the error easily (by solving the linear constraint a->c == 0) In summary, all bugs reported by DART are guaranteed to be sound! But DART may not terminate…

PLDI’2005Page 21June 2005 DART for C: Implementation Details prgm.c dart test_driver.c prgm_instrumented.c dart.c Constraint solver(s) (e.g., lp_solve.so) prgm.exe C compiler CIL (Berkeley) Error found Complete coverage Run forever… 3 possible outcomes: (OCaml, C)

PLDI’2005Page 22June 2005 Experiments: NS Authentication Protocol Tested a C implementation of a security protocol (Needham- Schroeder) with a known attack –About 400 lines of C code; experiments on a Linux 800Mz P-III machine –DART takes less than 2 seconds (664 runs) to discover a (partial) attack, with an unconstrained (possibilistic) intruder model –DART takes 18 minutes (328,459 runs) to discover a (full) attack, with a realistic (Dolev-Yao) intruder model –DART found a new bug in this C implementation of Lowe’s fix to the NS protocol (after 22 minutes of search; bug confirmed by the code’s author) In contrast, a systematic state-space search of this program composed with a concurrent nondeterministic intruder model using VeriSoft (a sw model checker) does not find the attack

PLDI’2005Page 23June 2005 A Larger Application: oSIP Open Source SIP library (Session Initiation Protocol) –30,000 lines of C code (version 2.0.9), 600 externally visible functions Results: –DART crashed 65% of the externally visible functions within 1000 runs –Most of these due to missing(?) NULL-checks for pointers… –Analysis of results for oSIP parser revealed a simple attack to crash it! oSIP version (August 2004) Int osip_message_parse (osip_message_t * sip, const char *buf) { [ … ] char *tmp; tmp = alloca (strlen (buf) + 2); osip_strncpy (tmp, buf, strlen (buf)); osip_util_replace_all_lws (tmp); [ etc. ] oSIP version (December 2004) Int osip_message_parse (osip_message_t * sip, const char *buf, size_t length) { [ … ] char *tmp; tmp = osip_malloc (length + 2); if (tmp==NULL) { [… print error msg and return –1; ] } osip_strncpy (tmp, buf, length); osip_util_replace_all_lws (tmp); [ etc. ] Attack: send a packet of size 2.5 MB (cygwin) with no 0 or “|” character alloca fails and returns NULLcrash!

PLDI’2005Page 24June 2005 Related Work Static analysis and automatic test generation based on static analysis: limited by symbolic execution technology (see above) Random testing (fuzz tools, etc.): poor coverage Dynamic test generation (Korel, Gupta-Mathur-Soffa, etc.) –Attempt to exercise a specific program –DART attempts to cover all executable program paths instead (like MC) –Also, DART handles function calls, unknown functions, exploits simultaneous concrete and symbolic executions, is sometimes complete (verification) and has run-time checks to detect incompleteness –DART is implemented for C and has been applied to large examples New: extension to deal with symbolic pointers [Sen et al., to appear in FSE’05] New: independent closely related work [Cadar-Engler, to appear in SPIN’05]

PLDI’2005Page 25June 2005 Conclusion DART = Directed Automated Random Testing Key strength/originality: –No manually-generated test driver required (fully automated) As automated as static analysis but with higher precision Starting point for testing process –No false alarms but may not terminate –Smarter than pure random testing (with directed search) –Can work around limitations of symbolic execution technology Symbolic execution is an adjunct to concrete execution Randomization helps where automated reasoning is difficult –Overall, complementary to static analysis…