The Low-Level Bounded Model Checker LLBMC

Similar documents
A Precise Memory Model for Low-Level Bounded Model Checking

Seminar in Software Engineering Presented by Dima Pavlov, November 2010

Homework 3 CS161 Computer Security, Fall 2008 Assigned 10/07/08 Due 10/13/08

Introduction to CBMC: Part 1

Handling Loops in Bounded Model Checking of C Programs via k-induction

Termination Analysis of C Programs Using Compiler Intermediate Languages

Lecture Notes on Real-world SMT

15-411: LLVM. Jan Hoffmann. Substantial portions courtesy of Deby Katz

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

A Brief Introduction to Using LLVM. Nick Sumner

Application of Propositional Logic II - How to Test/Verify my C program? Moonzoo Kim

MLSA: a static bugs analysis tool based on LLVM IR

Symbolic and Concolic Execution of Programs

Bounded Model Checking Of C Programs: CBMC Tool Overview

unsigned char memory[] STACK ¼ 0x xC of address space globals function KERNEL code local variables

Final CSE 131B Spring 2004

TI2725-C, C programming lab, course

Targeting LLVM IR. LLVM IR, code emission, assignment 4

Baggy bounds with LLVM

Introduction to Programming Using Java (98-388)

Introduction to CBMC. Software Engineering Institute Carnegie Mellon University Pittsburgh, PA Arie Gurfinkel December 5, 2011

C Code Verification based on the Extended Labeled Transition System Model

Machine-Level Programming V: Unions and Memory layout

Programming Fundamentals - A Modular Structured Approach using C++ By: Kenneth Leroy Busbee

In Java we have the keyword null, which is the value of an uninitialized reference type

CS558 Programming Languages

Deductive Methods, Bounded Model Checking

Memory Corruption 101 From Primitives to Exploit

Short Notes of CS201

ESBMC 1.22 (Competition Contribution) Jeremy Morse, Mikhail Ramalho, Lucas Cordeiro, Denis Nicole, Bernd Fischer

CS201 - Introduction to Programming Glossary By

: A Bounded Model Checking Tool to Verify Qt Applications

A Context-Sensitive Memory Model for Verification of C/C++ Programs

Verifying C & C++ with ESBMC

Under the Compiler's Hood: Supercharge Your PLAYSTATION 3 (PS3 ) Code. Understanding your compiler is the key to success in the gaming world.

Declaring Pointers. Declaration of pointers <type> *variable <type> *variable = initial-value Examples:

Understanding Pointers

Kurt Schmidt. October 30, 2018

Bug Finding with Under-approximating Static Analyses. Daniel Kroening, Matt Lewis, Georg Weissenbacher

System LAV and Its Applications

CSolve: Verifying C With Liquid Types

Software Model Checking. Xiangyu Zhang

Plan for Today. Concepts. Next Time. Some slides are from Calvin Lin s grad compiler slides. CS553 Lecture 2 Optimizations and LLVM 1

Symbolic Execution. Joe Hendrix Galois, Inc SMT Summer School galois

SMT-Based Bounded Model Checking for Embedded ANSI-C Software. Lucas Cordeiro, Bernd Fischer, Joao Marques-Silva

Roadmap. Java: Assembly language: OS: Machine code: Computer system:

Memory (Stack and Heap)

MEMORY MANAGEMENT TEST-CASE GENERATION OF C PROGRAMS USING BOUNDED MODEL CHECKING

Secure Programming. An introduction to Splint. Informatics and Mathematical Modelling Technical University of Denmark E

CMSC 350: COMPILER DESIGN

CS 322 Operating Systems Programming Assignment 4 Writing a memory manager Due: November 16, 11:30 PM

Development of a Translator from LLVM to ACL2

Static Program Checking

More on Verification and Model Checking

Low level security. Andrew Ruef

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

Final CSE 131B Spring 2005

Automatic Software Verification

CS2141 Software Development using C/C++ C++ Basics

Model Checking Embedded C Software using k-induction and Invariants

Overview AEG Conclusion CS 6V Automatic Exploit Generation (AEG) Matthew Stephen. Department of Computer Science University of Texas at Dallas

PRINCIPLES OF OPERATING SYSTEMS

HECTOR: Formal System-Level to RTL Equivalence Checking

CSE 333 Lecture 4 - malloc, free, struct, typedef

Introduction to C Language (M3-R )

Sendmail crackaddr - Static Analysis strikes back

CS 267: Automated Verification. Lecture 13: Bounded Model Checking. Instructor: Tevfik Bultan

C Programming. Course Outline. C Programming. Code: MBD101. Duration: 10 Hours. Prerequisites:

Review of the C Programming Language for Principles of Operating Systems

COSC Software Engineering. Lecture 16: Managing Memory Managers

Intermediate Code Generation

CS558 Programming Languages

Satisfiability Modulo Theories: ABsolver

GNATprove a Spark2014 verifying compiler Florian Schanda, Altran UK

OptiCode: Machine Code Deobfuscation for Malware Analysis

CSI33 Data Structures

Putting the Checks into Checked C. Archibald Samuel Elliott Quals - 31st Oct 2017

EL2310 Scientific Programming

Homework I - Solution

Creating Formally Verified Components for Layered Assurance with an LLVM-to-ACL2 Translator

Reasoning About LLVM Code Using Codewalker

CSC 1600 Memory Layout for Unix Processes"

Lectures 5-6: Introduction to C

When you add a number to a pointer, that number is added, but first it is multiplied by the sizeof the type the pointer points to.

CSE 351: The Hardware/Software Interface. Section 2 Integer representations, two s complement, and bitwise operators

Predicting the Resilience of Obfuscated Code Against Symbolic Execution Attacks via Machine Learning

Lectures 5-6: Introduction to C

Static Program Analysis Part 1 the TIP language

Review: C Strings. A string in C is just an array of characters. Lecture #4 C Strings, Arrays, & Malloc

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

Contents of Lecture 3

Lecture 07 Heap control data. Stephen Checkoway University of Illinois at Chicago

BITCOIN MINING IN A SAT FRAMEWORK

C#: framework overview and in-the-small features

Lecture Notes on Memory Layout

Motivation was to facilitate development of systems software, especially OS development.

Lexical Considerations

Splitting the Control Flow with Boolean Flags

Systems Programming and Computer Architecture ( )

Tutorial 1: Introduction to C Computer Architecture and Systems Programming ( )

Transcription:

The Low-Level Bounded Model Checker LLBMC A Precise Memory Model for LLBMC Carsten Sinz Stephan Falke Florian Merz October 7, 2010 VERIFICATION MEETS ALGORITHM ENGINEERING KIT University of the State of Baden-Wuerttemberg and National Research Center of the Helmholtz Association www.kit.edu

Motivation Buffer overflows are still the number one issue as reported in OS vendor advisories. (... ) Integer overflows, barely in the top ten overall in the past few years, are number two for OS vendor advisories (in 2006), behind buffer overflows Use-after-free vulnerability in Microsoft Internet Explorer (... ) allows remote attackers to execute arbitrary code by accessing a pointer associated with a deleted object (... ) Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 2/19

What is LLBMC? LLBMC = Low-Level (Software) Bounded Model Checking Low-Level: Not operating on source code but on abstract assembler Software: Programs written in C/C++/Objective C and compiled into abstract assembler Bounded: restricted number of nested function calls and loop iterations Model Checking: bit-precise static analysis Properties checked: Built-in properties: invalid memory accesses, use-after-free, double free, range overflow, division by zero,... User-supplied properties: assert statements Focus on memory properties Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 3/19

Software Bounded Model Checking Programs typically deal with unbounded data structures such as linked lists, trees, etc. Property checking is undecidable for these programs Bugs manifest themselves in (typically short) finite runs of the program Software bounded model checking: Analyze only bounded program runs Restrict number of nested function calls and inline functions Restrict number of loop iterations and unroll loops Data structures are then bounded as well Property checking becomes decidable by a logical encoding into SAT or SMT Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 4/19

Specifying and Verifying Properties Properties are formalized using assume and assert statements assume states a pre-condition that is assumed to hold at its location assert states a post-condition that is to be checked at its location The program Prog is correct if is valid Prog assume assert In software bounded model checking, this can be decided using a logical encoding and a SAT or SMT solver Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 5/19

Low Level Bounded Model Checking Fully supporting real-life programming languages is cumbersome Particularly true for C/C++/Objective C due to their complex (sometimes ambiguous) semantics Key idea: Do not operate on the source code directly, use a compiler intermediate language ( abstract assembler ) instead Well-defined, simple semantics makes logical encoding easier Closer to the code that is actually run Compiler optimizations etc. come for free LLBMC uses the LLVM intermediate language and compiler infrastructure After the logical encoding, LLBMC uses the SMT solver Boolector (theory of bitvectors and arrays) Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 6/19

Overview of the LLBMC Approach LLVM Compiler Frontend Loop Unrolling / Function Inlining Logical Encoding SMT Solver Program Source Code Abstract Assembler Representation Transformed Assembler Representation Bit-Vector Logic with Arrays Verification Result / Error Trace Memory Model Memory model captures the semantics of memory accesses Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 7/19

Example %s t r u c t. S = type { i32, %s t r u c t. S } struct S { i n t x ; struct S n ; } ; i n t main ( i n t argc, char argv [ ] ) { struct S p, q ; } p = malloc ( sizeof ( struct S ) ) ; p >x = 5; p >n = NULL ; i f ( argc > 1) { q = malloc ( sizeof ( struct S ) ) ; q >x = 5; q >n = p ; } else { q = p ; } l l b m c a s s e r t ( p >x + q >x == 10); f r e e ( q ) ; f r e e ( p ) ; return 0; define i32 @main( i32 %argc, i8 %argv ) { entry : %0 = c a l l i 8 @malloc ( i32 8) %p = b i t c a s t i8 %0 to %s t r u c t. S %p. x = getelementptr %s t r u c t.s %p, i32 0, i32 0 s t o r e i32 5, i32 %p. x %p. n = getelementptr %s t r u c t. S %p, i32 0, i32 1 store %s t r u c t. S null, %s t r u c t. S %p. n %c.1 = icmp sgt i32 %argc, 1 br i 1 %c.1, l a b e l %i f. then, l a b e l %i f.end i f. then : %1 = c a l l i 8 @malloc ( i32 8) %q = b i t c a s t i8 %1 to %s t r u c t. S %q. x = getelementptr %s t r u c t.s %q, i32 0, i32 0 s t o r e i32 5, i32 %q. x %q. n = getelementptr %s t r u c t. S %q, i32 0, i32 1 store %s t r u c t. S %p, %s t r u c t. S %q. n br label %i f. end i f. end : %q.0 = phi %s t r u c t. S [ %q, %i f. then ], [ %p, %entry ] %q.0. x = getelementptr %s t r u c t.s %q.0, i32 0, i32 0 %2 = load i32 %p. x %3 = load i32 %q.0. x %4 = add i32 %2, %3 %c.2 = icmp eq i32 %4, 10 %5 = zext i 1 %c.2 to i32 c a l l void @ llbmc assert ( i32 %5) %6 = b i t c a s t %s t r u c t. S %q.0 to i8 c a l l void @free ( i 8 %6) %7 = b i t c a s t %s t r u c t. S %p to i8 c a l l void @free ( i 8 %7) r e t i32 0 } Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 8/19

Encoding of phi-instructions The abstract assembler contains phi-instructions of the form i = phi[i 1, bb 1 ],..., [i n, bb n ] where bb 1,..., bb n are basic blocks For the logical encoding, bb j is replaced by where c exec (bb j ) t(bb j, b) c exec (bb j ) is bb j s execution condition b is the basic block containing the phi-instruction t(bb j, b) is the condition under which control passes from bb j to b Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 9/19

Elimination of branches The memory can be modelled as an array of bytes SSA form for the memory by introducing an abstract type memstate: Memory is accessed using read-instructions Memory is changed using write-, malloc-, and free-instructions phi-instructions for memory states are introduced With the encoding of phi-instructions and the conversion of the memory to SSA form branches can be eliminated Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 10/19

Example %s t r u c t. S = type { i32, %s t r u c t. S } define i32 @main( i32 %argc, i8 %argv ) { entry : %0 = c a l l i 8 @malloc ( i32 8) %p = b i t c a s t i8 %0 to %s t r u c t. S %p. x = getelementptr %s t r u c t.s %p, i32 0, i32 0 s t o r e i32 5, i32 %p. x %p. n = getelementptr %s t r u c t. S %p, i32 0, i32 1 store %s t r u c t. S null, %s t r u c t. S %p. n %c.1 = icmp sgt i32 %argc, 1 br i 1 %c.1, l a b e l %i f. then, l a b e l %i f.end i f. then : %1 = c a l l i 8 @malloc ( i32 8) %q = b i t c a s t i8 %1 to %s t r u c t. S %q. x = getelementptr %s t r u c t.s %q, i32 0, i32 0 s t o r e i32 5, i32 %q. x %q. n = getelementptr %s t r u c t. S %q, i32 0, i32 1 store %s t r u c t. S %p, %s t r u c t. S %q. n br label %i f. end i f. end : %q.0 = phi %s t r u c t. S [ %q, %i f. then ], [ %p, %entry ] %q.0. x = getelementptr %s t r u c t.s %q.0, i32 0, i32 0 %2 = load i32 %p. x %3 = load i32 %q.0. x %4 = add i32 %2, %3 %c.2 = icmp eq i32 %4, 10 %5 = zext i 1 %c.2 to i32 c a l l void @ llbmc assert ( i32 %5) %6 = b i t c a s t %s t r u c t. S %q.0 to i8 c a l l void @free ( i 8 %6) %7 = b i t c a s t %s t r u c t. S %p to i8 c a l l void @free ( i 8 %7) r e t i32 0 } s t r u c t. S = s t r u c t { i32, s t r u c t. S } memstate %mem0 i 8 %0 memstate %mem1 = malloc(%mem0, %0, 8) struct. S %p = bitcast (%0) i32 %p. x = getelementptr(%p, 0, 0) memstate %mem2 = store(%mem1, %p. x, 5) s t r u c t.s %p. n = getelementptr(%p, 0, 1) memstate %mem3 = store(%mem2, %p. n, n u l l ) i32 %argc i 1 %c.1 = %argc > 1 i 8 %1 memstate %mem4 = malloc(%mem3, %1, 8) struct. S %q = bitcast (%1) i32 %q. x = getelementptr(%q, 0, 0) memstate %mem5 = store(%mem4, %q. x, 5) s t r u c t.s %q. n = getelementptr(%q, 0, 1) memstate %mem6 = s t o r e(%mem5, %q. n, %p ) memstate %mem7 = phi ([%mem3,!%c. 1 ], [%mem6, %c. 1 ] ) s t r u c t. S %q.0 = phi ([%p,!%c. 1 ], [%q, %c. 1 ] ) i32 %q. 0. x = getelementptr(%q.0, 0, 0) i32 %2 = load(%mem7, %p. x ) i32 %3 = load(%mem7, %q. 0. x ) i32 %4 = add(%2, %3) i 1 %c.2 = %4 == 10 assert(%c. 2 ) memstate %mem8 = f r e e (%mem7, %q. 0 ) memstate %mem9 = free(%mem8, %p ) ; Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 11/19

Encoding Memory Constraints 1 The following memory checks are built-in: Valid read/writes (i.e., only to allocated memory) Valid frees (i.e., free is only called for the beginning of a block of allocated memory) No double frees (i.e., no memory block is free d twice) Building blocks: valid mem access(m, p, s): the range p,..., p + s 1 is allocated in the memory state m deallocated(m, m, p): the block beginning at p is free d between m and m... Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 12/19

Memory Modification Graph Example s t r u c t. S = s t r u c t { i32, s t r u c t. S } memstate %mem0 i 8 %0 memstate %mem1 = malloc(%mem0, %0, 8) s t r u c t. S %p = b i t c a s t (%0) i32 %p. x = getelementptr(%p, 0, 0) memstate %mem2 = store(%mem1, %p. x, 5) s t r u c t. S %p. n = getelementptr(%p, 0, 1) memstate %mem3 = store(%mem2, %p. n, n u l l ) i32 %argc i 1 %c.1 = %argc > 1 i 8 %1 memstate %mem4 = malloc(%mem3, %1, 8) s t r u c t. S %q = b i t c a s t (%1) i32 %q. x = getelementptr(%q, 0, 0) memstate %mem5 = store(%mem4, %q. x, 5) s t r u c t. S %q. n = getelementptr(%q, 0, 1) memstate %mem6 = s t o r e(%mem5, %q. n, %p ) m 0 m1 = malloc(m0, p, 8) m 1 m2 = store(m1, p, 5) m 2 m3 = store(m2, pn, NULL) m m4 = malloc(m3, q, 8) 3 m 4 m5 = store(m4, q, 5) m 5 m6 = store(m5, qn, p) memstate %mem7 = phi ([%mem3,!%c. 1 ], [%mem6, %c. 1 ] ) s t r u c t. S %q.0 = phi ([%p,!%c. 1 ], [%q, %c. 1 ] ) i32 %q.0. x = getelementptr(%q.0, 0, 0) i32 %2 = load(%mem7, %p. x ) i32 %3 = load(%mem7, %q.0. x ) i32 %4 = add(%2, %3) i 1 %c.2 = %4 == 10 assert(%c. 2 ) memstate %mem8 = f r e e (%mem7, %q. 0 ) memstate %mem9 = f r e e (%mem8, %p ) ; m 7 m 8 m 9 m8 = free(m7, q0) m9 = free(m8, p) m 6 m7 = phi [m6,c1] [m3, c1] Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 13/19

Encoding Memory Constraints 2 m m : c exec (I): there exists a path from m to m in the memory modification graph execution condition of the (basic block containing the) instruction I deallocated(m, m, p) c exec(i) p = q m m m I: m = free( ˆm,q) valid mem access(m, p, s) m m I: m = malloc( ˆm,q,t) c exec(i) (q p q + t s) deallocated(m, m, q) Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 14/19

Encoding Memory Constraints 3 Each m = write(m, p, x) and each x = read(m, p) is preceded by the assertion valid mem access(m, p, s) where s is the appropriate size Similar assertions are added for the other built-in memory checks For malloc-instructions, assumptions on disjointness of the allocated memory regions are added Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 15/19

Example s t r u c t. S = s t r u c t { i32, s t r u c t. S } memstate %i n i t i a l M e m S t a t e i 8 %0 i 1 %2 = 0x00000000 <= ( void )%0 i32 %4 = add ( ( i32 )%0, 7) i 1 %6 = 0 x 5 f f f f f f f >= ( void )%4 i 1 %7 = ( void )%0 <= ( void )%4 i 1 %8 = and(%2, %6) i 1 %9 = and(%8, %7) assume ( malloc assume, %9, 1) memstate %11 = malloc ( heap, %initialmemstate, %0, 8, 1) i32 %p. x = getelementptr ( ( s t r u c t.s )%0, 0, 0) i 1 %13 = 0 x b f f f f f f f < ( void )%p. x i32 %14 = add ( ( i32)%p. x, 3) i 1 %16 = 0 x b f f f f f f f >= ( void )%14 i 1 %17 = and(%13, %16) i 1 %18 = %0 <= %p. x i32 %19 = add ( ( i32)%p. x, 4) i32 %21 = add ( ( i32 )%0, 8) i 1 %23 = ( void )%19 <= ( void )%21 i 1 %24 = and(%18, %23) i 1 %25 = or (%17, %24) assert ( v a l i d s t o r e, %25, 1) memstate %27 = s t o r e (%11, %p. x, 5, 1) s t r u c t.s %p. n = getelementptr ( ( s t r u c t.s )%0, 0, 1) i 1 %29 = 0 x b f f f f f f f < ( void )%p. n i32 %30 = add ( ( i32)%p. n, 3) i 1 %32 = 0 x b f f f f f f f >= ( void )%30 i 1 %33 = and(%29, %32) i1 %34 = %0 <= %p. n i32 %35 = add ( ( i32)%p. n, 4) i 1 %37 = ( void )%35 <= ( void )%21 i 1 %38 = and(%34, %37) i 1 %39 = or (%33, %38) assert ( v a l i d s t o r e, %39, 1) memstate %41 = s t o r e (%27, %p. n, 0x00000000, 1) i32 %argc i 1 %c.1 = %argc > 1 i 8 %42 i 1 %44 = 0x00000000 <= ( void )%42 i32 %46 = add ( ( i32 )%42, 7) i 1 %48 = 0 x 5 f f f f f f f >= ( void )%46 i 1 %49 = ( void )%42 <= ( void )%46 i 1 %50 = and(%44, %48) i 1 %51 = and(%50, %49) i32 %52 = add ( ( i32 )%42, 8) i 1 %54 = ( void )%52 <= ( void )%0 i 1 %55 = ( void )%21 <= ( void )%42 i 1 %56 = or (%54, %55) i 1 %57 = and(%51, %56) assume (malloc assume, %57, %c.1) memstate %59 = malloc ( heap, %41, %42, 8, %c. 1 ) i32 %q. x = getelementptr ( ( s t r u c t.s )%42, 0, 0) i 1 %61 = 0 x b f f f f f f f < ( void )%q. x i32 %62 = add ( ( i32)%q. x, 3) i 1 %64 = 0 x b f f f f f f f >= ( void )%62 i 1 %65 = and(%61, %64) i 1 %66 = %0 <= %q. x i32 %67 = add ( ( i32)%q. x, 4) i 1 %69 = ( void )%67 <= ( void )%21 i 1 %70 = and(%66, %69) i 1 %71 = %42 <= %q. x i 1 %72 = ( void )%67 <= ( void )%52 i 1 %73 = and(%71, %72) i 1 %74 = and(%c. 1, %73) i 1 %75 = or (%70, %74) i 1 %76 = or (%65, %75) assert ( v a l i d s t o r e, %76, %c. 1 ) assert ( v a l i d s t o r e, %76, %c. 1 ) memstate %78 = s t o r e (%59, %q. x, 5, %c. 1 ) s t r u c t.s %q. n = getelementptr ( ( s t r u c t.s )%42, 0, 1) i 1 %80 = 0 x b f f f f f f f < ( void )%q. n i32 %81 = add ( ( i32)%q. n, 3) i 1 %83 = 0 x b f f f f f f f >= ( void )%81 i 1 %84 = and(%80, %83) i1 %85 = %0 <= %q. n i32 %86 = add ( ( i32)%q. n, 4) i 1 %88 = ( void )%86 <= ( void )%21 i 1 %89 = and(%85, %88) i1 %90 = %42 <= %q. n i 1 %91 = ( void )%86 <= ( void )%52 i 1 %92 = and(%90, %91) i 1 %93 = and(%c. 1, %92) i 1 %94 = or (%89, %93) i 1 %95 = or (%84, %94) assert ( v a l i d s t o r e, %95, %c. 1 ) memstate %97 = store (%78, %q. n, ( s t r u c t.s )%0, %c. 1 ) void %stacktopptr0 = phi ( [0 x b f f f f f f f,!%c. 1 ], [0 x b f f f f f f f, %c. 1 ] ) memstate %i f. end mem = phi ([%41,!%c. 1 ], [%97, %c. 1 ] ) s t r u c t.s %q.0 = phi ( [ ( s t r u c t.s )%0,!%c.1], [ ( s t r u c t.s )%42, %c.1]) i32 %q.0. x = getelementptr(%q.0, 0, 0) i1 %98 = %stacktopptr0 < ( void )%p. x i 1 %99 = and(%98, %16) i1 %100 = %42 <= %p. x i 1 %101 = ( void )%19 <= ( void )%52 i 1 %102 = and(%100, %101) i 1 %103 = and(%c. 1, %102) i 1 %104 = or (%24, %103) i 1 %105 = or (%99, %104) assert ( v a l i d l o a d, %105, 1) i32 %107 = load(% i f.end mem, %p.x, 1) i1 %109 = %stacktopptr0 < ( void )%q.0. x i32 %110 = add ( ( i32)%q. 0. x, 3) i 1 %112 = 0 x b f f f f f f f >= ( void )%110 i 1 %113 = and(%109, %112) i1 %114 = %0 <= %q.0. x i32 %115 = add ( ( i32)%q. 0. x, 4) i 1 %117 = ( void )%115 <= ( void )%21 i 1 %118 = and(%114, %117) i1 %119 = %42 <= %q.0. x i 1 %120 = ( void )%115 <= ( void )%52 i 1 %121 = and(%119, %120) i 1 %122 = and(%c. 1, %121) i 1 %123 = or (%118, %122) i 1 %124 = or (%113, %123) assert ( v a l i d l o a d, %124, 1) i32 %126 = load(% i f.end mem, %q.0.x, 1) i32 %127 = add(%107, %126) i 1 %c.2 = %127 == 10 i 1 %129 = ( i 8 )%q.0 == %0 i 1 %130 = ( i 8 )%q.0 == %42 i 1 %131 = and(%c. 1, %130) i 1 %132 = or (%129, %131) assert ( v a l i d f r e e, %132, %c. 2 ) i 1 %134 = %0 == %0 i 1 %135 = %0 == ( i 8 )%q.0 i 1 %136 = and(%c. 2, %135) i 1 %138 = and(%134,!%136) i 1 %139 = %0 == %42 i 1 %140 = %42 == ( i 8 )%q.0 i 1 %141 = and(%c. 2, %140) i 1 %143 = and(%139,!%141) i 1 %144 = and(%c. 1, %143) i 1 %145 = or (%138, %144) assert ( v a l i d f r e e, %145, %c. 2 ) a s s e r t ( custom, 0,!%c. 2 ) Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 16/19

Example (Memory Management) struct S { i n t x ; struct S n ; } ; i n t main ( i n t argc, char argv [ ] ) { struct S p, q ; p = malloc ( sizeof ( struct S ) ) ; p >x = 5; p >n = NULL ; i f ( argc > 1) { q = malloc ( sizeof ( struct S ) ) ; q >x = 5; q >n = p ; } else { q = p ; } l l b m c a s s e r t ( p >x + q >x == 10); f r e e ( q ) ; f r e e ( p ) ; } return 0; Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 17/19

Example (Functional Correctness) i n t npo2 ( i n t x ) { unsigned i n t i ; x ; for ( i = 1; i < sizeof ( int ) 8; i = 2) { x = x ( x >> i ) ; } return x + 1; } i n t main ( i n t argc, char argv [ ] ) { i n t x = argc ; llbmc assume ( x > 0 && x < ( INT MAX >> 1 ) ) ; i n t n = npo2 ( x ) ; l l b m c a s s e r t ( n >= x ) ; l l b m c a s s e r t ( n < ( x << 1 ) ) ; l l b m c a s s e r t ( ( n & ( n 1 ) ) == 0 ) ; } return 0; Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 18/19

Future Work Optimization of memory constraints Discharging of simple memory constraints using: Rewriting Restricted linear arithmetic Boolean simplification... Dedicated SMT solver for memory properties Function inlining and loop unrolling on demand Modular verification Handling system calls (strings, memory copy, etc.) Carsten Sinz, Stephan Falke, Florian Merz LLBMC October 7, 2010 19/19