Chapter Six - Symbolic Execution and Recent Applications to Worst-Case Execution, Load Testing, and Security Analysis
Introduction
As computer systems become more pervasive and complex, it has become increasingly important to develop techniques and tools that effectively ensure software dependability. Symbolic execution [1] is a systematic program analysis technique which explores multiple program behaviors at once, by collecting and solving symbolic path conditions collected over program paths. Symbolic execution can be used for finding bugs in software, where it checks for runtime errors or assertion violations during execution and it generates test inputs that trigger those errors.
Nowadays there are many symbolic execution tools available [[2], [3], [4], [5], [6], [7]] which have found numerous vulnerabilities and other interesting bugs in software. Much of the success of symbolic execution in recent years is due to significant advances in constraint solving and decision procedures [8, 9] as well as to the availability of increasingly cheap computational power and cloud computing platforms [4, 5], allowing to scale the technique to large applications.
In this chapter we review symbolic execution and associated tools, and we describe the main challenges in applying symbolic execution in practice: handling of programs with complex inputs, coping with path explosion, and ameliorating the cost of constraint solving. We also survey some applications of the technique that go beyond checking functional properties of programs. These include finding worst-case execution time in programs, load testing and security analysis, via combinations of symbolic execution with fuzzing. These applications are perhaps less studied in the literature but we believe they hold much promise for the future. We conclude with directions for future work.
Section snippets
Symbolic Execution
Symbolic execution [1] is a program analysis technique that executes a program on symbolic, instead of concrete, input values and computes the effects of the program as functions in terms of these symbolic inputs. The result of symbolically executing a program is a set of symbolic paths, each with a path condition PC, which is a conjunction of constraints over the symbolic inputs that characterizes all the inputs that follow that path. All the PCs are disjoint.
When executing a branching
Tools and Scalability Challenges
Because of its capability of finding subtle bugs, and its applications in a widespread of domains, symbolic execution has been developed on several platforms, for different programming languages. The following table contains a (likely incomplete) list of symbolic executors. Language Tool Link Java (bytecode) Symbolic PathFinder [3] https://babelfish.arc.nasa.gov/trac/jpf/wiki/projects/jpf-symbc Java StarFinder [19] https://github.com/star-finder/jpf-star jCUTE https://github.com/osl/jcute janala2 //github.com/ksen007/janala2
Worst-Case Execution Time (WCET) Analysis
Symbolic execution has been used in several works related to real-time systems. Real-time systems are characterized by having timing requirements in addition to functional requirements. As an example, systems operating in the safety-critical domain often have hard temporal requirements on responding to stimuli from the environment, such as an airbag that must be deployed within a specific time frame upon collision.
An important aspect of real-time systems is the Worst-Case Execution Time (WCET)
Conclusion
In this chapter we reviewed symbolic execution techniques and tools and we described recent applications, including finding worst-case execution time in programs, load testing and security analysis, via combinations of symbolic execution with fuzzing. There are other promising directions for symbolic execution, among them the extension of symbolic execution to probabilistic reasoning [94, 95], with applications to reliability analysis and quantitative information flow (which we described
Corina S. Păsăreanu is an associate research professor with CyLab at Carnegie Mellon University, working at the Silicon Valley campus with NASA Ames Research Center. She is an ACM Distinguished Scientist, known for her influential research on software model checking, symbolic execution and assume-guarantee compositional verification, using abstraction and learning-based methods. She is the recipient of an ACM SIGSOFT Distinguished Paper Award in 2002, the ICSE 2010 Most Influential Paper Award,
References (96)
- et al.
Complete worst-case execution time analysis of straight-line hard real-time programs
J. Syst. Archit.
(2000) Symbolic execution and program testing
Commun. ACM
(1976)- et al.
KLEE: unassisted and automatic generation of high-coverage tests for complex systems programs
- et al.
Symbolic pathfinder: integrating symbolic execution with model checking for Java bytecode analysis
Autom. Softw. Eng.
(2013) - et al.
Cloud9: a software testing service
SIGOPS Oper. Syst. Rev.
(2010) - et al.
SAGE: whitebox fuzzing for security testing
Queue
(2012) - et al.
Unleashing mayhem on binary code
- et al.
Driller: Augmenting Fuzzing Through Selective Symbolic Execution
- et al.
Z3: an efficient SMT solver
- et al.
Automata-Based Model Counting for String Constraints
DART: directed automated random testing
A dynamic approach of test data generation
Generalized symbolic execution for model checking and testing
Bogor/Kiasan: a K-bounded symbolic execution for checking strong heap properties of open systems
Towards a case-optimal symbolic execution algorithm for analyzing strong properties of object-oriented programs
Exact heap summaries for symbolic execution
Bounded lazy initialization
Test input generation with Java PathFinder
Symbolic execution of programs with heap inputs
Enhancing symbolic execution of heap-based programs with separation logic for test input generation
CoRR
BI as an assertion language for mutable data structures
Separation logic: a logic for shared mutable data structures
Satisfiability Modulo Heap-Based Programs
JDart: a dynamic symbolic analysis framework
JBSE: a symbolic executor for java programs with complex heap inputs
BAP: a binary analysis platform
S2E: a platform for in-vivo multi-path analysis of software systems
CUTE: a concolic unit testing engine for C
KLOVER: a symbolic execution and automatic test generation tool for C++ programs
EXE: automatically generating inputs of death
A symbolic execution framework for Javascript
SymDroid: symbolic execution for Dalvik bytecode
Deconstructing dynamic symbolic execution
BitBlaze: a new approach to computer security via binary analysis
Statically-directed dynamic automated test generation
Symbooglix: a symbolic execution engine for boogie programs
Distributed Parallel Symbolic Execution
ParSym: parallel symbolic execution
Parallel symbolic execution for structural test generation
Unit checking: symbolic model checking for a unit of code
Compositional dynamic test generation
Demand-driven compositional symbolic execution
Efficient state merging in symbolic execution
Enhancing symbolic execution with veritesting
MultiSE: multi-path symbolic execution using value summaries
Compositional symbolic execution with memoized replay
Boosting concolic testing via interpolation
Automatic partial loop summarization in dynamic test generation
Cited by (0)
Corina S. Păsăreanu is an associate research professor with CyLab at Carnegie Mellon University, working at the Silicon Valley campus with NASA Ames Research Center. She is an ACM Distinguished Scientist, known for her influential research on software model checking, symbolic execution and assume-guarantee compositional verification, using abstraction and learning-based methods. She is the recipient of an ACM SIGSOFT Distinguished Paper Award in 2002, the ICSE 2010 Most Influential Paper Award, the 2010 ACM SIGSOFT Impact Paper Award, the ISSTA 2018 Retrospective Impact Paper Award, the ASE 2018 Most Influential Paper Award, and the ESEC/FSE 2018 Test of Time Award. More information is available at her website: https://ti.arc.nasa.gov/profile/pcorina/.
Rody Kersten is a senior software engineer at Synopsys, in the Core Analysis team for the Coverity Static Application Security Testing product. He has received an MSc (2010) and PhD (2015) in Computer Science from Radboud University Nijmegen in The Netherlands. He is a former postdoctoral researcher at Carnegie Mellon University, and a former assistant professor at Open University of the Netherlands. His research interests include static analysis, formal verification, symbolic execution, and fuzz testing, with a focus on software resource consumption (time, memory, energy). As a software engineer, he has contributed to a variety of software analysis applications, including the industry-leading Static Application Security Testing product Coverity.
Kasper Søe Luckow is a software development engineer in the Automated Reasoning Group at Amazon Web Services. He received a BSc degree (2009) and MSc Cum Laude degree (2011) in Software Engineering from Aalborg University and a PhD degree (2014) in Computer Science from the same university. From 2014 to 2017 he was a postdoctoral researcher at Carnegie Mellon University. His research interests include program analysis, verification, and testing.
Quoc-Sang Phan is currently a member of research staff at Fujitsu Laboratories of America. He received his PhD degree in Computer Science from Queen Mary University of London in 2015. From 2015 to 2017, he was a postdoctoral researcher at Carnegie Mellon University. His research interests include symbolic execution and fuzzing techniques for software security.