aa r X i v : . [ c s . P L ] S e p Automated Verification of Integer Overflow
Asankhaya Sharma SourceClear
Corresponding author:Asankhaya Sharma Email address: [email protected]
ABSTRACT
Integer overflow accounts for one of the major source of bugs in software. Verification systems typically assumea well defined underlying semantics for various integer operations and do not explicitly check for integer overflowin programs. In this paper we present a specification mechanism for expressing integer overflow. We develop anautomated procedure for integer overflow checking during program verification. We have implemented a prototypeinteger overflow checker and tested it on a benchmark consisting of already verified programs (over 14k LOC). Wehave found 43 bugs in these programs due to integer overflow.
INTRODUCTION
Numerical errors in software are quite common and yet are ignored by most verifications systems. Integer overflow inparticular has been among the top 25 software bugs (Christey et al., 2011). These errors can lead to serious failures andexploitable vulnerabilities. Program verification helps to build reliable software by ensuring that relevant properties ofcan be validated. In Hoare logic style program verification we typically specify programs using pre and post conditions.The verifier assumes an underlying well defined semantics and generates proofs of correctness of program. Mostverification systems do not check for errors due to undefined behaviors in programs. In C/C++ the integer operationsmay lead to undefined behaviors as specified by the standard. Undefined behaviors in the C/C++ specification leadto confusion among programmers. Moreover many programmers expect wrap around behavior for integer overflow(Dietz et al., 2012) and may intentionally write code that leads to such overflows. The code written with undefined (inthe language specification) intentional overflows is not guaranteed to be portable and the behavior may depend on theoptimizations used in various compilers.It is no surprise that automated verifiers typically assume a well defined semantics for various integer operations.However in order to increase the completeness of verification it is desirable to specify and verify integer overflow.The starting point of this work is the HIP/SLEEK verification system (Chin et al., 2011) based on separation logic.HIP/SLEEK system can do automated verification of shape, size and bag properties of programs (Chin et al., 2012).We extend the domain of integers (extended number line) with two logical infinite constants ∞ and − ∞ , correspondingto positive and negative infinity respectively. Even though this kind extension of integers is common in librariesfor programming languages for portability reasons, it is eventually typically mapped to a fixed value for a particularunderlying architecture (32-bit or 64-bit). In a verification setting we find it better to enrich the underlying specificationlogic with these constants and reason with them automatically during entailment. This mechanism allows us to specifyintentional and unintentional integer overflow in programs. In particular our key contributions are • A specification mechanism for integer overflows using logical infinities • Entailment procedure for handling logical infinities • Integrated integer overflow checking with automated verification • A prototype implementation of an Integer overflow checker • Finding 43 integer overflow bugs in existing benchmark of verified programshe rest of the paper is structured as follows. In the next section, we motivate our approach with a few examples.Then we present our specification language with logical infinities. This specification language is used to describeautomated verification with integer overflow checking. We also formulate some soundness properties of our system.In the experiments section we present our implementation with a benchmark of already verified programs. We describesome related work and finally we conclude in the last section.
MOTIVATING EXAMPLES
We illustrate the integration of integer overflow checking in a verification system by means of few examples. Thefollowing function increments the value passed to it. void ex1 ( int n ) requires n ≥ = n + ; { return n + ; } If the value of n that is passed to this function is the maximum value that can be represented by the underlyingarchitecture this program will lead to an integer overflow. In order to avoid dealing with absolute values of maximumand minimum integers we introduce a logical constant ∞ in the specification language. With this constant it is possibleto write the specification for the function to avoid integer overflow. void ex2 ( int n ) requires 0 ≤ n + < ∞ ensures res = n + ; { return n + ; } Another benefit of adding this constant to the specification language is that it allows users to specify intentionalinteger overflow. A recent study (Dietz et al., 2012) has found intentional integer overflow occurs frequently in realcodes. We allow a user to express integer overflow using ∞ constant where such behavior is well defined. Thefollowing example shows how to specify intentional overflow. void ex3 ( int n ) requires n ≥ ( n + < ∞ ∧ res = n + ) ∨ ( n + ≥ ∞ ∧ ( true ) ioc ) ; { return n + ; } In this example we use the error calculus from (Le et al., 2013) to specify integer overflow with an error status( ioc ). This error status is verified and propagated during entailment. Details of the error validation and localizationmechanism are given in (Le et al., 2013). Use of logical infinity constants ( ∞ ) enable us to specify intentional integeroverflow as an explicit error scenario in the method specification. Another benefit of using an enhanced specificationmechanism (with ∞ constants) is that we can integrate integer overflow checking in an expressive logic like separationlogic. This addresses two major problems faced by static integer overflow checkers - tracking integer overflow throughheap and integer overflows inside data structures. As an example consider the following method which returns the sumof values inside a linked list. 2 ata { int val ; node next } ll h root , sum i≡ ( root = null ∧ sum = ) ∨∃ d , q · ( root node h d , q i∗ ll h q , rest i ) ∧ sum = d + rest ∧ sum < ∞ int ex4 ( node x ) requires ll h x , s i ensures ll h x , s i∧ res = s { if ( x == null ) return 0 ; elsereturn x . val + ex4 ( x . next ) ; } We can specify the linked list using a predicate in separation logic ( ll ). In the predicate definition we use ∞ constant to express the fact that the sum of values in the list cannot overflow. With this predicate we can now writethe pre/post condition for the function ex4 . During verification we can now check that the sum of values of linked listwill not lead to an integer overflow. A common security vulnerability that can be exploited using Integer overflow isthe buffer overrun. The following example ( ex5 ) shows how two character arrays can be concatenated. We expressthe bounds on the domain of arrays using a relation dom . This program can lead to an integer overflow if the sum ofthe size of two arrays is greater than the maximum integer that can be represented by the underlying architecture. Bycapturing the explicit condition under which this function can lead to an integer overflow ( ioc ) we can verify andprevent buffer overrun. We again use the ∞ logical constant in the precondition to specify the integer overflow. dom ( char [] c , int low , int high ) dom ( c , low , high ) ∧ low ≤ l ∧ h ≤ high = ⇒ dom ( c , l , h ) int ex5 ( ref char [] buf1 , char [] buf2 , size t len1 , size t len2 ) requires dom ( buf1 , , len1 ) ∧ dom ( buf2 , , len2 ) ∧ len1 + len2 ≤ = ∧ dom ( buf1 , , len1 + len2 ) ; requires dom ( buf1 , , len1 ) ∧ dom ( buf2 , , len2 ) ∧ len1 + len2 > = − ∧ dom ( buf1 , , len1 ) ; requires dom ( buf1 , , len1 ) ∧ dom ( buf2 , , len2 ) ∧ len1 + len2 > ∞ ensures ( true ) ioc ; { char buf [ ] ; if ( len1 + len2 > ) return − ; memcpy ( buf , buf1 , len1 ) ; memcpy ( buf + len1 , buf2 , len2 ) ; buf1 = buf ; return 0 ; } Using ∞ constant as part of the specification language we can represent various cases of integer overflows in aconcise manner. In this way we also avoid multiple constants like INT MAX, INT MIN etc., typically found in headerfiles for various architectures. When compared to other approaches, this specification mechanism is more suited tofinding integer overflows during verification.Exploitable vulnerabilities caused by integer overflows can also be prevented by specifications preventing overflowusing ∞ . The following example (taken from (Dowd et al., 2006)) shows how integer overflow checking can prevent3etwork buffer overrun. For brevity we show only part of the functions and omit the specification for the method aswell. The function ex6 reads an integer from the network and performs some sanity checks on it. First, the length ischecked to ensure that it’s greater than or equal to zero and, therefore, positive. Then the length is checked to ensurethat it’s less than MAXCHARS. However, in the second part of the length check, 1 is added to the length. This opensa possibility of the following buffer overrun: A value of INT MAX passes the first check (because it’s greater than0) and passes the second length check (as INT MAX + 1 can wrap around to a negative value). read() would then becalled with an effectively unbounded length argument, leading to a potential buffer overflow situation. This situationcan be prevented by using the specifications given for the network get int method that ensures that length is alwaysless than ∞ . int network get int ( int sockfd ) requires trueensures res < ∞ ; char ∗ ex6 ( int sockfd ) { char buf ; int length = network get int ( sockfd ) ; if ( ! ( buf = ( char ∗ ) malloc ( MAXCHARS ))) die ( “ malloc : % m ′′ ) ; if ( length < || length + > = MAXCHARS ) { free ( buf ) ; die ( “ badlength : % d ′′ , value ) ; } if ( read ( sockfd , buf , length ) < = ) { free ( buf ) ; die ( “ read : % m ′′ ) ; } return buf ; } SPECIFICATION LANGUAGE
We present the specification language of our system which is extended from (Chin et al., 2012) with the addition of aconstant representing logical infinity. The detailed language is depicted in figure 1. Φ pr ∗→ Φ po captures a precondition Φ pr and a postcondition Φ po of a method or a loop. They are abbreviated from the standard representation requires Φ pr and ensures Φ po , and formalized by separation logic formula Φ . In turn, the separation logic formula is adisjunction of a heap formula and a pure formula ( κ ∧ π ). The pure part π captures a rich constraint from the domainsof Presburger arithmetic (supported by Omega solver (Pugh, 1992)), monadic set constraint (supported by MONAsolver (Klarlund and Moller, 2001)) or polynomial real arithmetic (supported by Redlog solver (Dolzmann and Sturm,1997)). Following the definitions of separation logic in (Ishtiaq and O’Hearn, 2001; Reynolds, 2002), the heap partprovides notation to denote emp heap, singleton heaps , and disjoint heaps ∗ .The major feature of our system compared to (Ishtiaq and O’Hearn, 2001; Reynolds, 2002) is the ability for userto define recursive data structures. Each data structure and its properties can be defined by an inductive predicate pred ,that consists of a name p , a main separation formula Φ and an optional pure invariant formula π that must hold forevery predicate instance. In addition to the integer constant k we now support a new infinite constant denoted by ∞ .This enables us to represent positive and negative infinities by ∞ and − ∞ respectively. For the following discussion weassume the existence of an entailment prover for separation logic (like (Chin et al., 2012)) and a solver for Presburgerarithmetic (like (Pugh, 1992)). We now focus only on integrating automated reasoning with the new infinite constant ∞ inside these existing provers. 4 red :: = p ( v ∗ ) ≡ Φ [ inv π ] mspec :: = Φ pr ∗→ Φ po Φ :: = W ( ∃ w ∗ · κ ∧ π ) ∗ κ :: = emp | v c ( v ∗ ) | p ( v ∗ ) | κ ∗ κ π :: = α | π ∧ π α :: = β | ¬ ββ :: = v = v | v = null | a ≤ a | a = a a :: = k | k × v | a + a | − a | max ( a , a ) | min ( a , a ) | ∞ where p is a predicate name ; v , w are variable names ; c is a data type name ; k is an integer constant ; Figure 1.
The Specification LanguageAn entailment prover for the specification language is used to discharge proof obligations generated during forwardverification. The entailment checking for separation logic formulas is typically represented (Chin et al., 2012) asfollows. Φ ⊢ Φ , Φ r This attempts to prove that Φ entails Φ with Φ r as its frame (residue) not required for proving Φ . This entailmentholds, if Φ = ⇒ Φ ∗ Φ r . Entailment provers for separation logic deal with the heap part ( κ ) of the formula andreduce the entailment checking to satisfiability queries over the pure part ( π ). We now show how this reasoning canbe extended to deal with the new constant representing infinity ( ∞ ). A satisfiability check over pure formula with ∞ is reduced to a satisfiability check over a formula without ∞ which can be discharged by using existing solvers (likeOmega). In order to eliminate ∞ from the formula we take help of the equisatisfiable normalization rules shown infigure 2 and proceed as follows. SAT ( π ) substitute equalities ( v = ∞ )= ⇒ SAT ([ v / ∞ ] π ) normalization = ⇒ SAT ( π ; π norm ) elimintate ∞ = ⇒ SAT ([ ∞ / v ∞ ] π norm ) We start with substituting any equalities with ∞ constants then we apply the normalization rules. The normalizationrules eliminate certain expressions containing ∞ based on comparison with integer constants ( k ) and variables ( v ). Weshow rules for both ∞ and − ∞ in figure 2. In the normalization rules we use a = a as a shorthand for ¬ ( a = a ) .During normalization, we may generate some equalities involving ∞ (in [ NORM − VAR − INF ] ). In that case, we normalizeagain after substituting the new equalities in the pure formula. Once no further equalities are generated we eliminatethe remaining ∞ constant if any by replacing it with a fresh integer variable v ∞ in the pure formula. The pure formulanow does not contain any infinite constants and a satisfiability check on the formula can now be done using existingmethods. 5 NORM − INF − INF ] ∞ = ∞ ; true ∞ = ∞ ; false ∞ ≤ ∞ ; true ∞ = − ∞ ; false ∞ = − ∞ ; true ∞ ≤− ∞ ; false − ∞ = − ∞ ; true − ∞ = − ∞ ; false − ∞ ≤− ∞ ; true − ∞ ≤ ∞ ; true [ NORM − CONST − INF ] k = ∞ ; false k = ∞ ; true k ≤ ∞ ; true ∞ ≤ k ; false k = − ∞ ; false k = − ∞ ; true k ≤− ∞ ; false − ∞ ≤ k ; true [ NORM − VAR − INF ] v ≤ ∞ ; true ∞ ≤ v ; v = ∞ v ≤− ∞ ; v = − ∞ − ∞ ≤ v ; true [ NORM − MIN − MAX ] min ( a , ∞ ) ; amax ( a , ∞ ) ; ∞ min ( a , − ∞ ) ; − ∞ max ( a , − ∞ ) ; a Figure 2.
Equisatisfiable NormalizationEnriching the specification language with infinite constants is quite useful as it allows users to specify properties(integer overflows) using ∞ as demostrated in the motivating examples. The underlying entailment procedure canautomatically handle ∞ by equisatisfiable normalization. VERIFICATION WITH INTEGER OVERFLOW
Our core imperative language is presented in figure 3. A program P comprises of a list of data structure declarations tdecl ∗ and a list of method declarations meth ∗ (we use the superscript ∗ to denote a list of elements). Data structuredeclaration can be a simple node datat or a recursive shape predicate declaration pred as shown in figure 1.A method is declared with a prototype, its body e , and multiple specification mspec ∗ . The prototype comprisesa method return type, method name and method’s formal parameters. The parameters can be passed by value orby reference with keyword ref and their types can be primitive τ or user-defined c . A method’s body consists ofa collection of statements. We provide basic statements for accessing and modifying shared data structures and forexplicit allocation of heap storage. It includes:1. Allocation statement: new c ( v ∗ ) Lookup statement: For simplifying the presentation but without loss of expressiveness, we just provide one-levellookup statement v . f rather than v . f . f .3. Mutation statement: v . f : = v In addition we provide core statements of an imperative language, such as semicolon statement e ; e , functioncall mn ( v ∗ ) , conditional statement if v e e , and loop statement while v e ( mspec ) ∗ . Note that for simplicity, wejust allow boolean variables (but not expression) to be used as the test conditions for conditional statements and loopstatement must be annotated with invariant through mspec ∗ . To illustrate some of the basic operations on integers in thelanguage we also show the addition operation between two integers (unsigned and signed) in figure 3 as k [ u ] int1 + k [ u ] int2 .We now present the modifications needed to do forward verification with interger overflow. The core language usedby our system is a C-like imperative language described in figure 3. The complete set of forward verification rules are6 :: = tdecl ∗ meth ∗ tdecl :: = datat | preddatat :: = data c { field ∗ } field :: = t vt :: = c | ττ :: = uint | int | bool | float | void meth :: = t mn (([ ref ] t v ) ∗ ) where ( mspec ) ∗ { e } e :: = null | k τ | k [ u ] int + k [ u ] int | v | v . f | v : = e | v . f : = v | new c ( v ∗ ) | e ; e | t v ; e | mn ( v ∗ ) | if v then e else e | while v do e ( mspec ) ∗ Figure 3.
A Core Imperative Languageas given in (Chin et al., 2012). We use P to denote the program being checked. With the pre/post conditions declaredfor each method in P, we can now apply modular verification to its body using Hoare-style triples ⊢ { ∆ } e { ∆ } . Weexpect ∆ to be given before computing ∆ since the rules are based on a forward verifier. To capture proof search,we generalize the forward rule to the form ⊢ { ∆ } e { Ψ } where Ψ is a set of heap states, discovered by a search-basedverification process (Chin et al., 2012). When Ψ is empty, the forward verification is said to have failed for ∆ asprestate. As most of the forward verification rules are standard (Nguyen et al., 2007), we only provide those for methodverification and method call. Verification of a method starts with each precondition, and proves that the correspondingpostcondition is guaranteed at the end of the method. The verification is formalized in the rule [ FV − [ METH ] ] : • function prime(V) returns { v ′ | v ∈ V } . • predicate nochange(V) returns V v ∈ V ( v = v ′ ) . If V = {} , nochange(V)=true . • ∃ W · Ψ returns {∃ W · Ψ i | Ψ i ∈ Ψ } . [ FV − [ METH ] ] V = { v m .. v n } W = prime ( V ) ∀ i = , .., p · ( ⊢ { Φ ipr ∧ nochange ( V ) } e { Ψ i } ( ∃ W · Ψ i ) ⊢ κ V , I Φ ipo ∗ Ψ i Ψ i = {} ) t mn (( ref t j v j ) m − j = , ( t j v j ) nj = m ) { requires Φ ipr ensures Φ ipo } pi = { e } At a method call, each of the method’s precondition is checked, ∆ ⊢ κ V , I ρΦ ipr ∗ Ψ i , where ρ represents a substitutionof v j by v ′ j , for all j = ,.., n . The combination of the residue Ψ i and the postcondition is added to the poststate. If aprecondition is not entailed by the program state ∆ , the corresponding residue is not added to the set of states. The test Ψ = {} ensures that at least one precondition is satisfied. Note that we use the primed notation for denoting the latestvalue of a variable. Correspondingly, [ v ′ / v i ] is a substitution that replaces the value v i with the latest value of v ′ . [ FV − [ CALL ] ] t mn (( ref t j v j ) m − j = , ( t j v j ) nj = m ) { requires Φ ipr ensures Φ ipo } pi = { e } ∈ P ρ =[ v ′ j / v j ] nj = m ∆ ⊢ κ V , I ρΦ ipr ∗ Ψ i ∀ i = , .., p Ψ = S pi = Φ ipo ∗ Ψ i Ψ = {}⊢ { ∆ } mn ( v .. v n ) { Ψ }
7n order to integrate integer overflow checking with automated verification we first translate the basic operations inthe core language (like integer addition) to method calls to specific functions which do integer overflow checking. Inthis paper we illustrate the verification using only the addition overflow, however similar translations can be done forother operators like multiplication (Moy et al., 2009) etc.. The addition operation for unsigned integers k uint1 + k uint2 is translated to the method uadd whose specification is given below. int uadd ( uint k , uint k ) requires k + k > ∞ ensures ( true ) ioc ; requires k + k ≤ ∞ ensures res = k + k ;The addition of unsigned integers overflows when their sum is greater than ∞ . The case of signed integer overflowhas several cases. We translate addition of signed integers to the method add . The specification of the add methodcovers all the cases for signed integer overflow as detailed in (Dannenberg et al., 2010). int add ( int k , int k ) requires k > ∧ k > ∧ k + k > ∞ ∨ k > ∧ k ≤ ∧ k + k < − ∞ ∨ k ≤ ∧ k > ∧ k + k < − ∞ ∨ k ≤ ∧ k ≤ ∧ k + k < ∞ ∧ k = ( true ) ioc ; requires k > ∧ k > ∧ k + k ≤ ∞ ∨ k > ∧ k ≤ ∧ k + k ≥− ∞ ∨ k ≤ ∧ k > ∧ k + k ≥− ∞ ∨ k ≤ ∧ k ≤ ∧ ( k + k ≥− ∞ ∨ k = ) ensures res = k + k ;The specification of these methods ( uadd and add ) uses the infinite constants ( ∞ and − ∞ ) from the enrichedspecification language given in the previous section. An expressive specification language reduces the task of integeroverflow checking to just specifying and verifying of appropriate methods. After translation of basic operators intomethod calls, during forward verification the [ FV − [ CALL ] ] rule will ensure that we check each operation for integeroverflow. Thus a simple encoding of basic operators and translation of the source program before verification enablesus to do integer overflow checking along with automated verification. SOUNDNESS
In this section we outline the soundness properties of our entailment procedure with infinities and the forward ver-ifier with integer overflow checking. We assume the soundness of the underlying entailment checker and verifier(Chin et al., 2012).
Lemma 1. (Equisatisfiable Normalization) If π ; π norm then SAT ( π ) = ⇒ SAT ( π norm ) and SAT ( π norm ) = ⇒ SAT ( π ) Proof
We sketch the proof for each normalization rule given in figure 2.case [ NORM − INF − INF ] : From the first rule we get, SAT ( ∞ = ∞ ) ≡ true and the normalization gives ∞ = ∞ ; true , since SAT ( true ) ≡ true we have, SAT ( ∞ = ∞ ) = ⇒ SAT ( ∞ = ∞ ; true ) and SAT ( ∞ = ∞ ; true ) = ⇒ SAT ( ∞ = ∞ ) .Hence the normalization preserves satisfiability of pure formulas. We can prove the other rules in [ NORM − INF − INF ] similarly.case [ NORM − CONST − INF ] : From the first rule we get, SAT ( k = ∞ ) ≡ false and the normalization gives k = ∞ ; false , since SAT ( false ) ≡ false
8e have,
SAT ( k = ∞ ) = ⇒ SAT ( k = ∞ ; false ) and SAT ( k = ∞ ; false ) = ⇒ SAT ( k = ∞ ) .Hence the normalization preserves satisfiability of pure formulas. We can prove the other rules in [ NORM − CONST − INF ] similarly.case [ NORM − VAR − INF ] : We sketch the proof for the following rule, SAT ( ∞ ≤ v ) ⇐⇒ SAT ( ∞ < v ∨ ∞ = v ) ⇐⇒ SAT ( false ∨ ∞ = v ) we have, SAT ( ∞ ≤ v ) = ⇒ SAT ( ∞ ≤ v ; v = ∞ ) and SAT ( ∞ ≤ v ; v = ∞ ) = ⇒ SAT ( ∞ ≤ v ) Hence the normalization preserves satisfiability of pure formulas. Other rules from [ NORM − VAR − INF ] can be provensimilarly.case [ NORM − MIN − MAX ] : We sketch the proof for the following rule, SAT ( max ( a , ∞ )) ⇐⇒ SAT (( a > ∞ = ⇒ a ) ∨ ( a ≤ ∞ = ⇒ ∞ )) ⇐⇒ SAT (( false = ⇒ a ) ∨ ( a ≤ ∞ = ⇒ ∞ )) ⇐⇒ SAT (( true ) ∨ ( a ≤ ∞ = ⇒ ∞ )) ⇐⇒ SAT ( a ≤ ∞ = ⇒ ∞ ) ⇐⇒ SAT ( true = ⇒ ∞ ) ⇐⇒ SAT ( ∞ ) we have, SAT ( max ( a , ∞ )) = ⇒ SAT ( max ( a , ∞ ) ; ∞ ) and SAT ( max ( a , ∞ ) ; ∞ ) = ⇒ SAT ( max ( a , ∞ )) Hence the normalization preserves satisfiability of pure formulas. Other rules from [ NORM − MIN − MAX ] can be provensimilarly. Lemma 2. (Soundness of Integer Overflow Checking)
If the program e has an integer overflow ( ioc ) then,with forward verification ⊢ { ∆ } e { Ψ } , we have ( true ) ioc ∈ Ψ Proof
Provided all basic operators on integers in the program are translated to method calls that check for integeroverflows. The soundness of integer overflow checking follows from lemma 1 and the soundness of error calculus(Le et al., 2013).The soundness of heap entailment and forward verification with separation logic based specifications is alreadyestablished in (Chin et al., 2012). Lemma 1 establishes that the normalization rules indeed preserve the satisfiabilityof pure formulas. Lemma 2 then shows that the integer overflow checking with forward verification is sound. If theprogram has an integer overflow the forward verification with integer overflow checking detects it.
EXPERIMENTS
We have implemented our approach in an OCaml prototype called
HIPioc evaluate automated verification using log-ical infinities ( ∞ ) we created benchmark of several programs that use infinite constants as sentinel values in searchingand sorting. As an example the following predicate definition of a sorted linked list uses ∞ in the base case to expressthat the minimum value in an empty list is infinity. data { int val ; node next } Sortedll h root , min i≡ ( root = null ∧ min = ∞ ) ∨∃ q · ( root node h min , q i∗ Sortedll h q , minrest i ) ∧ min < minrest In addition,
HIPioc allows us to do integer overflow checking of programs during verification. We have run
HIPioc on several existing verification benchmarks which contain different kinds of programs. The benchmarks Available at http://loris-5.d2.comp.nus.edu.sg/SLPAInf/SLPAInf.ova (md5sum 4afb66d65bfa442726717844f46eb7b6)
Sorting ( with ∞ ) are the programs which use ∞ as sentinel value in predicate definitions as described above and do not contain integeroverflows. Comparing the times between HIPioc and previous version we see that the verification with ∞ in generaladds some overhead. Benchmark LOC Num o f Time Time Integer FalsePrograms ( Total ) Programs ( Secs ) (
HIPioc ) Over f lows PositivesSorting ( with ∞ )
282 4 5 .
45 5 .
42 0 0
Arrays .
92 76 .
65 1 0
HIP / SLEEK (Chin et al., 2012) 5779 42 56 .
15 78 .
80 4 0
Imm (David and Chin, 2011) 2069 11 120 .
82 126 .
61 18 0
V Perm (Le et al., 2012) 778 14 3 .
43 3 .
46 3 0
Barriers (Hobor and Gherghina, 2012) 1281 10 60 .
54 60 .
83 16 0
SIR (Le et al., 2013) 2616 4 34 .
64 41 .
73 1 1
Total .
95 393 . RELATED WORK
There has been considerable interest in recent years to detect and prevent integer overflows in software (Cotroneo and Natella,2012). Dietz et al. (Dietz et al., 2012) present a study of integer overflows in C/C++ programs. They find out thatintentional and unintentional integer overflows are prevalent in system software. Integer overflows often lead to ex-ploitable vulnerabilities in programs (Christey et al., 2011). In this paper we presented a method to detect uninten-tional integer overflows and provided a mechanism to specify intentional integer overflows. Program transformations(Coker and Hafiz, 2013) can be used to guide the programmer and aid in refactoring the source code to avoid integeroverflows. Our focus is on specification of intentional integer overflows which helps make the conditions under whichthe program may use an integer overflow explicit. It also aids in automated verification as such cases can be validatedas error scenarios for the program.Most existing techniques for detecting integer overflows are focused on dynamic checking and testing of programs(Molnar et al., 2009; Wang et al., 2009; Chen et al., 2009; Brumley et al., 2007). Dynamic analysis suffers from thepath explosion problem and although several improvements in constraints solving have been proposed (Sharma, 2012,2013) the approach cannot guarantee the absence of integer overflows. There are not many verification or staticanalysis tool that can do integer overflow checking. KINT (Wang et al., 2012) is a static analysis tool which candetect integer overflows by solving constraints generated from source code of programs. Another static analysis basedapproach by Moy et al. (Moy et al., 2009) uses the Z3 solver to do integer overflow checking as part of the PREFIXtool (Bush et al., 2000). A certified prover for presburger arithmetic extended with positive and negative infinities hasbeen described in (Sharma, 2015; Sharma et al., 2015).Our focus in this paper is on integrating integer overflow checking with program verification to improve the re-liability of verified software. Dynamic techniques may not explore all paths in the programs while static techniquessuffer form loss of precision in tracking integer overflows. Our specification mechanism allows us to integrate integeroverflow checking inside a prover for specification logic. This allows us to track integer overflows through the heapand inside various data structures. The benefit of this integration is that we can detect numeric integer overflow errorsin programs with complex sharing and heap manipulation.10
ONCLUSION
Integer overflows are a major source of errors in programs. Most verification systems do not focus on the underlyingnumeric operations on integers and do not handle integer overflow checking. We presented a technique to do integeroverflow checking of programs during verification. Our specification mechanism also allows expressing intentionaluses of integer overflows. We implemented a prototype of our proposal inside an existing verifier and found realinteger overflow bugs in benchmarks of verified software.
REFERENCES
Brumley, D., Song, D. X., cker Chiueh, T., Johnson, R., and Lin, H. (2007). Rich: Automatically protecting againstinteger-based vulnerabilities. In
NDSS . 10Bush, W. R., Pincus, J. D., and Sielaff, D. J. (2000). A static analyzer for finding dynamic programming errors.
Softw.Pract. Exper. , 30(7):775–802. 10Chen, P., Wang, Y., Xin, Z., Mao, B., and Xie, L. (2009). Brick: A binary tool for run-time detecting and locatinginteger-based vulnerability. In
Availability, Reliability and Security, 2009. ARES ’09. International Conference on ,pages 208–215. 10Chin, W.-N., David, C., and Gherghina, C. (2011). A hip and sleek verification system. In
OOPSLA Companion ,pages 9–10. 1Chin, W.-N., David, C., Nguyen, H. H., and Qin, S. (2012). Automated verification of shape, size and bag propertiesvia user-defined predicates in separation logic.
Sci. Comput. Program. , 77(9):1006–1036. 1, 4, 5, 7, 8, 9, 10Christey, S., Martin, R. A., Brown, M., Paller, A., and Kirby, D. (2011). 2011 CWE/SANS Top 25 Most DangerousSoftware Errors. Technical report, MITRE Corporation. http://cwe.mitre.org/top25. 1, 10Coker, Z. and Hafiz, M. (2013). Program transformations to fix c integers. In
Proceedings of the 2013 InternationalConference on Software Engineering , ICSE 2013. 10Cotroneo, D. and Natella, R. (2012). Monitoring of aging software systems affected by integer overflows. In
SoftwareReliability Engineering Workshops (ISSREW), 2012 IEEE 23rd International Symposium on , pages 265–270. 10Dannenberg, R. B., Dormann, W., Keaton, D., Seacord, R. C., Svoboda, D., Volkovitsky, A., Wilson, T., and Plum, T.(2010). As-if infinitely ranged integer model. In
Proceedings of the 2010 IEEE 21st International Symposium onSoftware Reliability Engineering , ISSRE ’10, pages 91–100, Washington, DC, USA. IEEE Computer Society. 8David, C. and Chin, W.-N. (2011). Immutable specifications for more concise and precise verification. In
OOPSLA ,pages 359–374. 10Dietz, W., Li, P., Regehr, J., and Adve, V. (2012). Understanding integer overflow in c/c++. In
Proceedings of the2012 International Conference on Software Engineering , ICSE 2012, pages 760–770, Piscataway, NJ, USA. IEEEPress. 1, 2, 10Dolzmann, A. and Sturm, T. (1997). Redlog: computer algebra meets computer logic.
SIGSAM Bull. , 31:2–9. 4Dowd, M., McDonald, J., and Schuh, J. (2006).
Art of Software Security Assessment, The: Identifying and PreventingSoftware Vulnerabilities . Addison-Wesley Professional. 3Hobor, A. and Gherghina, C. (2012). Barriers in concurrent separation logic: Now with tool support!
Logical Methodsin Computer Science , 8(2). 10Ishtiaq, S. and O’Hearn, P. (2001). BI as an assertion language for mutable data structures. In
ACM POPL , pages14–26, London. 4Klarlund, N. and Moller, A. (2001). MONA Version 1.4 - User Manual. BRICS Notes Series. 4Le, D.-K., Chin, W.-N., and Teo, Y. M. (2012). Variable permissions for concurrency verification. In
ICFEM , pages5–21. 10Le, Q. L., Sharma, A., Craciun, F., and Chin, W.-N. (2013). Towards complete specifications with an error calculus.In
NASA Formal Methods . 2, 9, 10Molnar, D., Li, X. C., and Wagner, D. A. (2009). Dynamic test generation to find integer bugs in x86 binary linuxprograms. In
Proceedings of the 18th conference on USENIX security symposium , SSYM’09, pages 67–82, Berkeley,CA, USA. USENIX Association. 10Moy, Y., Bjørner, N., and Sielaff, D. (2009). Modular bug-finding for integer overflows in the large: Sound, efficient,bit-precise static analysis. Technical report, Microsoft Research. 8, 1011guyen, H., David, C., Qin, S., and Chin, W. (2007). Automated Verification of Shape And Size Properties viaSeparation Logic. In
VMCAI , pages 251–266. 7Pugh, W. (1992). The Omega Test: A fast practical integer programming algorithm for dependence analysis.
Commu-nications of the ACM , 8:102–114. 4Reynolds, J. (2002). Separation Logic: A Logic for Shared Mutable Data Structures. In
IEEE LICS , pages 55–74. 4Sharma, A. (2012). A critical review of dynamic taint analysis and forward symbolic execution. Technical report,National University of Singapore. 10Sharma, A. (2013). An empirical study of path feasibility queries. arXiv preprint arXiv:1302.4798 . 10Sharma, A. (2015).
Certified Reasoning for Automated Verification . PhD thesis, National University of Singapore. 10Sharma, A., Wang, S., Costea, A., Hobor, A., and Chin, W.-N. (2015). Certified reasoning with infinity. In
Interna-tional Symposium on Formal Methods , pages 496–513. Springer. 10Wang, T., Wei, T., Lin, Z., and Zou, W. (2009). Intscope: Automatically detecting integer overflow vulnerability inx86 binary using symbolic execution. In
NDSS . 10Wang, X., Chen, H., Jia, Z., Zeldovich, N., and Kaashoek, M. F. (2012). Improving integer security for systems withkint. In