Automated Tools for Software Reliability Suhabe Bugrara Stanford University.

Slides:



Advertisements
Similar presentations
Dataflow Analysis for Datarace-Free Programs (ESOP 11) Arnab De Joint work with Deepak DSouza and Rupesh Nasre Indian Institute of Science, Bangalore.
Advertisements

Advanced programming tools at Microsoft
The Static Driver Verifier Research Platform
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Modular and Verified Automatic Program Repair Francesco Logozzo, Thomas Ball RiSE - Microsoft Research Redmond.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Finding bugs: Analysis Techniques & Tools Comparison of Program Analysis Techniques CS161 Computer Security Cho, Chia Yuan.
Data-Flow Analysis Framework Domain – What kind of solution is the analysis looking for? Ex. Variables have not yet been defined – Algorithm assigns a.
SPLINT STATIC CHECKING TOOL Sripriya Subramanian 10/29/2002.
1 Thorough Static Analysis of Device Drivers Byron Cook – Microsoft Research Joint work with: Tom Ball, Vladimir Levin, Jakob Lichtenberg,
Chair of Software Engineering Software Verification Stephan van Staden Lecture 10: Model Checking.
Thomas Ball, Rupak Majumdar, Todd Millstein, Sriram K. Rajamani Presented by Yifan Li November 22nd In PLDI 01: Programming Language.
Using Programmer-Written Compiler Extensions to Catch Security Holes Authors: Ken Ashcraft and Dawson Engler Presented by : Hong Chen CS590F 2/7/2007.
The Software Model Checker BLAST by Dirk Beyer, Thomas A. Henzinger, Ranjit Jhala and Rupak Majumdar Presented by Yunho Kim Provable Software Lab, KAIST.
Taming Win32 Threads with Static Analysis Jason Yang Program Analysis Group Center for Software Excellence (CSE) Microsoft Corporation.
Software Verification via Refinement Checking Sagar Chaki, Edmund Clarke, Alex Groce, CMU Somesh Jha, Wisconsin.
Checking and Inferring Local Non-Aliasing Alex AikenJeffrey S. Foster UC BerkeleyUMD College Park John KodumalTachio Terauchi UC Berkeley.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar Shaz Qadeer.
Scalable Error Detection using Boolean Satisfiability 1 Yichen Xie and Alex Aiken Stanford University.
Type-Safe Programming in C George Necula EECS Department University of California, Berkeley.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar [UC Berkeley] Shaz Qadeer [Microsoft Research]
Program analysis Mooly Sagiv html://
Synergy: A New Algorithm for Property Checking
Speeding Up Dataflow Analysis Using Flow- Insensitive Pointer Analysis Stephen Adams, Tom Ball, Manuvir Das Sorin Lerner, Mark Seigle Westley Weimer Microsoft.
CS 267: Automated Verification Lectures 14: Predicate Abstraction, Counter- Example Guided Abstraction Refinement, Abstract Interpretation Instructor:
Program analysis Mooly Sagiv html://
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball and Sriram K. Rajamani Software Productivity Tools, Microsoft Research Presented.
Program Analysis for Security Suhabe Bugrara Stanford University.
DART Directed Automated Random Testing Patrice Godefroid, Nils Klarlund, and Koushik Sen Syed Nabeel.
Software Reliability Methods Sorin Lerner. Software reliability methods: issues What are the issues?
Verifying the Safety of User Pointer Dereferences Suhabe Bugrara Stanford University Joint work with Alex Aiken.
Temporal-Safety Proofs for Systems Code Thomas A. Henzinger Ranjit Jhala Rupak Majumdar George Necula Westley Weimer Grégoire Sutre UC Berkeley.
Overview of program analysis Mooly Sagiv html://
MULTIVIE W Checking System Rules Using System-Specific, Program-Written Compiler Extensions Paper: Dawson Engler, Benjamin Chelf, Andy Chou, and Seth Hallem.
Program Analysis Mooly Sagiv Tel Aviv University Sunday Scrieber 8 Monday Schrieber.
Symbolic Path Simulation in Path-Sensitive Dataflow Analysis Hari Hampapuram Jason Yue Yang Manuvir Das Center for Software Excellence (CSE) Microsoft.
Statically Detecting Likely Buffer Overflow Vulnerabilities David Larochelle David Evans University of Virginia Department of Computer Science Supported.
Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b.
DART: Directed Automated Random Testing Koushik Sen University of Illinois Urbana-Champaign Joint work with Patrice Godefroid and Nils Klarlund.
Towards Scalable Modular Checking of User-defined Properties Thomas Ball, MSR Brian Hackett, Mozilla Shuvendu Lahiri, MSR Shaz Qadeer, MSR Julien Vanegue,
Mining Windows Kernel API Rules Jinlin Yang 09/28/2005CS696.
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 3: Modular Verification with Magic, Predicate Abstraction.
Rule Checking SLAM Checking Temporal Properties of Software with Boolean Programs Thomas Ball, Sriram K. Rajamani Microsoft Research Presented by Okan.
Aditya V. Nori, Sriram K. Rajamani Microsoft Research India.
Inferring Specifications to Detect Errors in Code Mana Taghdiri Presented by: Robert Seater MIT Computer Science & AI Lab.
Newton: A tool for generating abstract explanations of infeasibility1 The Problem P (C Program) BP (Boolean Program of P) CFG(P) CFG(BP)
Saturn Overview1 An Overview of the Saturn Project.
David Evans These slides: Introduction to Static Analysis.
Lazy Abstraction Jinseong Jeon ARCS, KAIST CS750b, KAIST2/26 References Lazy Abstraction –Thomas A. Henzinger et al., POPL ’02 Software verification.
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball, Sriram K. MSR Presented by Xin Li.
What is Testing? Testing is the process of finding errors in the system implementation. –The intent of testing is to find problems with the system.
1 Splint: A Static Memory Leakage tool Presented By: Krishna Balasubramanian.
Model Checking C Programs Zijiang (James) Yang Department of Computer Science Western Michigan University In collaboration with NEC Laboratories America.
The Yogi Project Software property checking via static analysis and testing Aditya V. Nori, Sriram K. Rajamani, Sai Deep Tetali, Aditya V. Thakur Microsoft.
Introduction to Software Analysis CS Why Take This Course? Learn methods to improve software quality – reliability, security, performance, etc.
Synergy: A New Algorithm for Property Checking Bhargav S. Gulavani (IIT Bombay)‏ Yamini Kannan (Microsoft Research India)‏ Thomas A. Henzinger (EPFL)‏
1 Automatically Validating Temporal Safety Properties of Interfaces - Overview of SLAM Parts of the slides are from
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
/ PSWLAB Evidence-Based Analysis and Inferring Preconditions for Bug Detection By D. Brand, M. Buss, V. C. Sreedhar published in ICSM 2007.
Verifying Regular Behavior of C modules Sagar Chaki, Edmund Clarke, Alex Groce, CMU Somesh Jha, Wisconsin.
Secure Coding Rules for C++ Copyright © 2016 Curt Hill
Content Coverity Static Analysis Use cases of Coverity Examples
APEx: Automated Inference of Error Specifications for C APIs
Ik-Soon Kim December 18, 2010 Embedded Software Platform Team
High Coverage Detection of Input-Related Security Faults
Verifying the Safety of User Pointer Dereferences
Language-based Security
Predicate Abstraction
Course: CS60030 Formal Systems
Presentation transcript:

Automated Tools for Software Reliability Suhabe Bugrara Stanford University

Problem 80% of development cost on identifying and correcting defects Software errors cost US economy $60 billion annually (0.6% of GDP)

Manual Testing Traditional approach to quality assurance Expensive Time consuming Not systematic Difficult to quantify effectiveness of test suite Cannot make any guarantees about reliability Insufficient for safety critical systems

Automated Tools Programs to find defects in programs Automated Systematic Easy to quantify effectiveness Provide guarantees about reliability Sometimes expensive (for now…) Sometimes time consuming (for now…)

Program Analyzers Sound Unsound CompleteIncomplete UndecidableDecidable Reports all errors May report false alarms Reports all errors Reports no false alarms May not report all errors May report false alarms Decidable May not report all errors Reports no false alarms

Static Driver Verifier Program analyzer for API usage rules Developed by Microsoft Research Applied to device drivers in Windows Sound: reports all possible errors Incomplete: may report false alarms

SDV: Overview 1.Write API usage rule specification 2.Instrument program with usage checks 3.Abstract program 4.Check abstraction for errors 5.If error found, see if error is false alarm 6.If false alarm, refine abstraction 7.If not false alarm, report error as bug

API Usage Rules Ex. locks are alternatingly acquired and released

API Usage Rules Ex. locks are alternatingly acquired and released Expressed as finite state machine –States = { locked, unlocked,error } –Transitions = { acquire(), release() }

API Usage Rules Ex. locks are alternatingly acquired and released Expressed as finite state machine –States = { locked, unlocked,error } –Transitions = { acquire(), release() } lockedunlocked error acquire(); release(); acquire();release();

state { enum { Unlocked=0; Locked=1} state = Unlocked; } KeAcquireSpinLock.return { if (state == Locked) error(); else state = Locked; } KeReleaseSpinLock.return { if (!(state == Locked)) error(); else state = Unlocked; }

enum {Unlocked=0, Locked=1} state = Unlocked void KeAcquireSpinLock_return() { if (state == Locked) error(); else state = Locked; } void KeReleaseSpinLock_return() { if (!(state == Locked)) error(); else state = Unlocked; }

1: void example() { 2: do { 3: KeAcquireSpinLock(); 4: 5:nPacketsOld = nPackets; 6:req = devExt->WLHV 7:if (req && req->status) { 8:devExt->WLHV = req->Next 9:KeReleaseSpinLock(); 10: 11:irp = req->irp; 12:if (req->status > 0) { 13:irp->IoS.Status = SUCCCESS; 14:irp->IoS.Info = req->Status; 15:} else { 16:irp->IoS.Status = FAIL; 17:irp->IoS.Info = req->Status; 18:} 19:SmartDevFreeBlock(req); 20:IoCompleteRequest(irp); 21:nPackets++; 22:} 23:} while (nPackets!=nPacketsOld); 24:KeReleaseSpinLock(); 25: 26: }

enum {Unlocked=0, Locked=1} state = Unlocked void KeAcquireSpinLock_return() { if (state == Locked) error(); else state = Locked; } void KeReleaseSpinLock_return() { if (!(state == Locked)) error(); else state = Unlocked; }

1: void example() { 2: do { 3: KeAcquireSpinLock(); 4:KeAcquireSpinLock_return(); 5:nPacketsOld = nPackets; 6:req = devExt->WLHV 7:if (req && req->status) { 8:devExt->WLHV = req->Next 9:KeReleaseSpinLock(); 10:KeReleaseSpinLock_return(); 11:irp = req->irp; 12:if (req->status > 0) { 13:irp->IoS.Status = SUCCCESS; 14:irp->IoS.Info = req->Status; 15:} else { 16:irp->IoS.Status = FAIL; 17:irp->IoS.Info = req->Status; 18:} 19:SmartDevFreeBlock(req); 20:IoCompleteRequest(irp); 21:nPackets++; 22:} 23:} while (nPackets!=nPacketsOld); 24:KeReleaseSpinLock(); 25:KeReleaseSpinLock_return(); 26: } Program A

SDV: Abstraction Construct abstraction B of original program A –Over-approximates reachability If error() is reachable in A, then it is also reachable in B –This characteristic makes SDV sound If error() is reachable in B, then it may not be reachable in A –This characteristic makes SDV incomplete Check abstraction B for any errors

Reachable States Original A error Abstraction B Sound: If A has error, then B has error real bug!

Reachable States Original A Abstraction B error Incomplete: If B has error, then A may not have error false alarm!

bool b1; b1 = false; Abstract state == Locked with b1 void KeAcquireSpinLock_return() { if (b1) error(); else b1 = true; } void KeReleaseSpinLock_return() { if (!(b1)) error(); else b1 = false; }

1: void example() { 2: do { 3: ; 4:KeAcquireSpinLock_return(); 5:; 6:; 7:if (SdvMakeChoice()) { 8:; 9:; 10:KeReleaseSpinLock_return(); 11:; 12:if (SdvMakeChoice()) { 13:; 14:; 15:} else { 16:; 17:; 18:} 19:; 20:; 21:; 22:} 23:} while (SdvMakeChoice()); 24:; 25:KeReleaseSpinLock_return(); 26: } Program B

1: void example() { 2: do { 3: ; 4:KeAcquireSpinLock_return(); 5:; 6:; 7:if (SdvMakeChoice()) { 8:; 9:; 10:KeReleaseSpinLock_return(); 11:; 12:if (SdvMakeChoice()) { 13:; 14:; 15:} else { 16:; 17:; 18:} 19:; 20:; 21:; 22:} 23:} while (SdvMakeChoice()); 24:; 25:KeReleaseSpinLock_return(); 26: } Error trace found!

1: void example() { 2: do { 3: KeAcquireSpinLock(); 4:KeAcquireSpinLock_return(); 5:nPacketsOld = nPackets; 6:req = devExt->WLHV 7:if (req && req->status) { 8:devExt->WLHV = req->Next 9:KeReleaseSpinLock(); 10:KeReleaseSpinLock_return(); 11:irp = req->irp; 12:if (req->status > 0) { 13:irp->IoS.Status = SUCCCESS; 14:irp->IoS.Info = req->Status; 15:} else { 16:irp->IoS.Status = FAIL; 17:irp->IoS.Info = req->Status; 18:} 19:SmartDevFreeBlock(req); 20:IoCompleteRequest(irp); 21:nPackets++; 22:} 23:} while (nPackets!=nPacketsOld); 24:KeReleaseSpinLock(); 25:KeReleaseSpinLock_return(); 26: } But, no bug in original program!

1: void example() { 2: do { 3: ; 4:KeAcquireSpinLock_return(); 5:b2 = false; 6:; 7:if (SdvMakeChoice()) { 8:; 9:; 10:KeReleaseSpinLock_return(); 11:; 12:if (SdvMakeChoice()) { 13:; 14:; 15:} else { 16:; 17:; 18:} 19:; 20:; 21:b2 = !b2 ? true : SdvMakeChoice(); 22:} 23:} while (b2); 24:; 25:KeReleaseSpinLock_return(); 26: } Program C

Reachable States Original A Abstraction B error Refined C false alarm no longer reported!

SDV: Summary 1.Write API usage rule specification 2.Instrument program with usage checks 3.Abstract program 4.Check abstraction for errors 5.If error found, see if error is false alarm 6.If false alarm, refine abstraction 7.If not false alarm, report error as bug

Soundness Assume memory safety –No buffer/integer overflows –Safe memory management –No null pointer dereferences Oversimplified harness –Use stubs to model calls into OS procedures –Stubs may not represent all behavior

Research Challenges in Verification Eliminate assumption of memory safety Eliminate false alarms Scale to the entire operating system Verify more complicated properties –prove consistency of file system data structures

Program Analyzers Sound Unsound CompleteIncomplete UndecidableDecidable Reports all errors May report false alarms Reports all errors Reports no false alarms May not report all errors May report false alarms Decidable May not report all errors Reports no false alarms

EXE Automatically generate test cases that explore important program paths Developed by Dawson Engler’s group Bug finding tool Unsound: may not report all errors Complete: never reports false alarms

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; }

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; }

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; } (x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x) find a solution using an automatic constraint solver… x = -1

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; } (x >= INT_MIN) && (x = 0) && (x = ) && (ret = -x) find a solution using an automatic constraint solver… x =

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; } (x >= INT_MIN) && (x = 0) && (x != ) && (ret = x) find a solution using an automatic constraint solver… x = 4

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; } EXE automatically generated test cases for each path… x = -1 x = x = 4

int bad_abs (int x) { if (x < 0) return –x; if (x == ) return –x; return x; }

1: int symbolic_bad_abs (int x) { 2:add_constraints(x >= INT_MIN, x <= INT_MAX); 3: ret = new symbol; 4: 5:if (fork() == child) { 6:add_constraints(x < 0, ret = -x); 7:return ret; 8: //(x >= INT_MIN) && (x <= INT_MAX) && (x < 0) && (ret = -x) 9:} else 10:add_constraints(x >= 0); 11: 12:if (fork() == child) { 13:add_constraints(x = , ret = -x); 14:return ret; 15: //(x >= INT_MIN) && (x = 0) && (x = ) 16: //&& (ret = -x) 17:} else 18:add_constraints(x != ); 19: 20:add_constraints(ret = x); 21:return ret; 22: //(x >= INT_MIN) && (x = 0) && (x != ) 23: && (ret = x) 24:}

1: int main (void) { 2:unsigned i, t, a[4] = { 1, 3, 5, 2}; 3:make_symbolic(&i); 4: 5:if (i >= 4) 6:exit(0); 7: 8:char *p = (char *) a + i * 4; 9:*p = *p – 1; 10: 11:t = a[*p]; 12: 13:t = t / a[i]; 14: 15:if (t == 2) 16:assert(i == 1); 17:else 18:assert(i == 3); 19: }

Review Why does SDV produce false alarms and EXE doesn’t? Why use SDV, then?

Saturn Large-scale program verification Developed by Alex Aiken’s group Sound: reports all errors Incomplete: may report false alarms Gives guarantees of reliability on systems as large as the Linux kernel with over 6.2 million lines of code

Program Analyzers Sound Unsound CompleteIncomplete UndecidableDecidable Reports all errors May report false alarms Reports all errors Reports no false alarms May not report all errors May report false alarms Decidable May not report all errors Reports no false alarms

Unchecked User Pointer Dereferences Security property of operating systems Two types of pointers in operating systems –kernel pointer: pointer created by the operating system –user pointer: pointer created by a user application and passed to the operating system via an entry point such as a system call Must check that a user pointer points into userspace before dereferencing it

Unchecked User Pointer Dereferences 1: static ssize_t read_port(…, char * __user buf, …) { 2:unsigned long i = *ppos; 3:char * __user tmp = buf; 4: 5:if (!access_ok(..,buf,...)) //check 6:return -EFAULT; 7: 8: while (count-- > 0 && i < 65536) { 9: if (__put_user(inb(i),tmp) < 0) //deref 10:return -EFAULT; 11:i++; 12:tmp++; 13:} 14: 15:*ppos = i; 16:return tmp-buf; 17: }

Security Vulnerability Malicious user could –Take control of the operating system –Overwrite kernel data structures –Read sensitive data out of kernel memory –Crash machine by corrupting data

Verifying the Security Property Eliminate the need for annotations Eliminate false positives Provide guarantee that no security vulnerabilities of this kind are present

Security Verifier Design a sound and incomplete verifier to prove statically that no unchecked user pointer dereferences exist

Security Verifier Compute set of facts at each program point States = { user, checked, error } Facts are pairs of locations and states –( *v,user) signifies that v is a user pointer Verify that program never in error state

Security Verifier Pointer is in user state if created by user application Pointer is in checked state if access_ok applied Pointer is in error state if dereferenced when 1.Pointer is in user state, AND 2.Pointer is NOT in checked state

Example 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

One Possible Approach …, but, procedure does not contain any vulnerabilities! (*u,user) (*u,error) emit warning! (*u,user) lost precision! (*u,user) (*u,checked) 1: int sys_call (int *u, int cmd) { 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u; 12:… (*u,user)

Path Sensitivity Ability to reason about branch correlations Important for reducing false positive rate Programs use substantial amount of branch correlation in practice

Example 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

Path Sensitivity Valid Path 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

Path Sensitivity Valid Path 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

Path Sensitivity Valid Path 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

Path Sensitivity Invalid Path! 1: int sys_call (int *u, int cmd) {//u is user pointer 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { //check u 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u;//dereference u 12:…

Path Sensitive Analysis (*u,user)  true (*u,checked)  cmd == 1 (*u,error)  cmd == 1 && !(cmd == 1) && true  false (*u,user)  true (*u,checked)  cmd == 1 (*u,user)  true (*u,checked)  cmd == 1 (*u,user)  true 1: int sys_call (int *u, int cmd) { 2: int x; 3: 4:if (cmd == 1) { 5:if (!access_ok(u)) { 6:return –ERR; 7:} 8:} 9:… 10:if (cmd == 1) 11:x = *u; 12:… (*u,user)  true

Design of Saturn Security Verifier Generate summary of behavior for each procedure with respect to calling context Apply summary of callee at call site in caller Repeatedly generate and apply summaries until a fixed point is reached

Experimental Setup Implemented verifier for unchecked user pointer dereferences Applied verifier to Linux built for x86 architecture 6.4 million lines of code Analyzed in 6 hours over 50 node cluster

Results 91,543 procedures 154 (.17%) of procedures time out 627 system call parameters 867,544 dereferences 15,452 (1.8%) of dereferences time out

Results Verified automatically –620 out of 627 system call arguments (99%) –851,914 out of 852,092 dereferences (99.96%) Warnings –7 warnings on system call arguments –278 warnings on dereferences –20 annotations required to verify

Saturn: Other Analyses Null pointer dereferences bug finder –Found hundreds of bugs in systems code –Isil Dillig, Thomas Dillig, and Alex Aiken. Static Error Detection Using Semantic Inconsistency Inference, PLDI 2007 Buffer overflow Safe casting Integer overflow Locking Safe memory management

Other Tools BLAST CQual Metal Daikon Vault ESP ESPX MOPS DART Prefast Failure Oblivious Computing CSSV Alloy eXplode Chord TVLA CCured Clouseau STeP Prefix

References A. Aiken et al. An Overview of the Saturn Project. PASTE 2007 T. Ball et al. Thorough Static Analysis of Device Drivers. EuroSys 2006 C. Cadar et al. EXE: Automatically Generating Inputs of Death. CCS 2006 C. Cadar et al. Execution Generated Test Cases: How to Make Systems Code Crash Itself. SPIN 2006 B. Hackett et al. Modular Checking for Buffer Overflows in the Large. ICSE J. Yang et al. Automatically generating malicious disks using symbolic execution. IEEE Security and Privacy 2006 Software Errors Cost U.S. Economy $59.5 Billion Annually. NIST