Elsevier

Advances in Computers

Volume 113, 2019, Pages 289-314
Advances in Computers

Chapter Six - Symbolic Execution and Recent Applications to Worst-Case Execution, Load Testing, and Security Analysis

https://doi.org/10.1016/bs.adcom.2018.10.004Get rights and content

Abstract

Symbolic execution is a systematic program analysis technique which executes programs on symbolic inputs, representing multiple concrete inputs, and represents the program behavior using mathematical constraints over the symbolic inputs. Solving the constraints with off-the-shelf solvers yields inputs that exercise different program paths. Typical applications of the technique include test input generation and error detection. In this chapter we review symbolic execution and associated tools, and describe some of 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 promising 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.

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.

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)

  • F. Stappert et al.

    Complete worst-case execution time analysis of straight-line hard real-time programs

    J. Syst. Archit.

    (2000)
  • J.C. King

    Symbolic execution and program testing

    Commun. ACM

    (1976)
  • C. Cadar et al.

    KLEE: unassisted and automatic generation of high-coverage tests for complex systems programs

  • C.S. Păsăreanu et al.

    Symbolic pathfinder: integrating symbolic execution with model checking for Java bytecode analysis

    Autom. Softw. Eng.

    (2013)
  • L. Ciortea et al.

    Cloud9: a software testing service

    SIGOPS Oper. Syst. Rev.

    (2010)
  • P. Godefroid et al.

    SAGE: whitebox fuzzing for security testing

    Queue

    (2012)
  • S.K. Cha et al.

    Unleashing mayhem on binary code

  • N. Stephens et al.

    Driller: Augmenting Fuzzing Through Selective Symbolic Execution

  • L. De Moura et al.

    Z3: an efficient SMT solver

  • A. Aydin et al.

    Automata-Based Model Counting for String Constraints

  • P. Godefroid et al.

    DART: directed automated random testing

  • B. Korel

    A dynamic approach of test data generation

  • S. Khurshid et al.

    Generalized symbolic execution for model checking and testing

  • X. Deng et al.

    Bogor/Kiasan: a K-bounded symbolic execution for checking strong heap properties of open systems

  • X. Deng et al.

    Towards a case-optimal symbolic execution algorithm for analyzing strong properties of object-oriented programs

  • B. Hillery et al.

    Exact heap summaries for symbolic execution

  • J. Geldenhuys et al.

    Bounded lazy initialization

  • W. Visser et al.

    Test input generation with Java PathFinder

  • P. Braione et al.

    Symbolic execution of programs with heap inputs

  • L.H. Pham et al.

    Enhancing symbolic execution of heap-based programs with separation logic for test input generation

    CoRR

    (2017)
  • S.S. Ishtiaq et al.

    BI as an assertion language for mutable data structures

  • J. Reynolds

    Separation logic: a logic for shared mutable data structures

  • Q.L. Le et al.

    Satisfiability Modulo Heap-Based Programs

  • K. Luckow et al.

    JDart: a dynamic symbolic analysis framework

  • P. Braione et al.

    JBSE: a symbolic executor for java programs with complex heap inputs

  • D. Brumley et al.

    BAP: a binary analysis platform

  • V. Chipounov et al.

    S2E: a platform for in-vivo multi-path analysis of software systems

  • K. Sen et al.

    CUTE: a concolic unit testing engine for C

  • G. Li et al.

    KLOVER: a symbolic execution and automatic test generation tool for C++ programs

  • C. Cadar et al.

    EXE: automatically generating inputs of death

  • P. Saxena et al.

    A symbolic execution framework for Javascript

  • J. Jeon et al.

    SymDroid: symbolic execution for Dalvik bytecode

    (2012)
  • T. Ball et al.

    Deconstructing dynamic symbolic execution

  • D. Song et al.

    BitBlaze: a new approach to computer security via binary analysis

  • D. Babić et al.

    Statically-directed dynamic automated test generation

  • D. Liew et al.

    Symbooglix: a symbolic execution engine for boogie programs

  • A. King

    Distributed Parallel Symbolic Execution

    (2009)
  • J.H. Siddiqui et al.

    ParSym: parallel symbolic execution

  • M. Staats et al.

    Parallel symbolic execution for structural test generation

  • E.L. Gunter et al.

    Unit checking: symbolic model checking for a unit of code

  • P. Godefroid

    Compositional dynamic test generation

  • S. Anand et al.

    Demand-driven compositional symbolic execution

  • V. Kuznetsov et al.

    Efficient state merging in symbolic execution

  • T. Avgerinos et al.

    Enhancing symbolic execution with veritesting

  • K. Sen et al.

    MultiSE: multi-path symbolic execution using value summaries

  • R. Qiu et al.

    Compositional symbolic execution with memoized replay

  • J. Jaffar et al.

    Boosting concolic testing via interpolation

  • P. Godefroid et al.

    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.

    View full text