Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Signed integer overflow is undefined behavior (see undefined behavior 36 in Annex J of the C Standard). This means that implementations have a great deal of latitude in how they deal with signed integer overflow.

An implementation may define the same modulo arithmetic for both unsigned as well as and signed integers. On such an implementation, signed integers overflow by wrapping around to zero0. An example of such an implementation is GNU GCC invoked with the -fwrapv command-line option.

Other implementations may cause a hardware trap (also called an exceptional condition) to be generated when a signed integer overflows. On such implementations, a program that causes a signed integer to overflow will most likely abnormally exit. On a UNIX system, the result of such an event may be a signal sent to the process. An example of such an implementation is GNU GCC invoked with the -ftrapv command-line option.

Other Still other implementations still may simply assume that signed integers never overflow and may generate object code accordingly. An example of such an implementation is GNU GCC invoked without either the -fwrapv or the -ftrapv option.

It is also possible for the same conforming implementation to emit code that exhibits different behavior in different contexts. For example, an implementation may determine that a signed integer loop control variable declared in a local scope cannot overflow and may emit efficient code based on the basis of that determination, while the same implementation may avoid making that assumption in another function when the variable is a global object.

...

Most integer operations can result in overflow if the resulting value cannot be represented by the underlying representation of the integer. The following table indicates which operators can result in overflow:

Operator

Overflow 

Operator

Overflow 

Operator

Overflow 

Operator

Overflow

+

Yes 

-=

Yes 

<<

Yes 

<

No

-

Yes 

*=

Yes 

>>

No 

>

No

*

Yes 

/=

Yes 

&

No 

>=

No

/

Yes 

%=

Yes 

|

No 

<=

No

%

Yes 

<<=

Yes 

^

No 

==

No

++

Yes 

>>=

No 

~

No 

!=

No

--

Yes 

&=

No 

!

No 

&&

No

=

No 

|=

No 

un +

No 

||

No

+=

Yes 

^=

No 

un -

Yes 

?:

No

The following sections examine specific operations that are susceptible to integer overflow. When operating on small integer types (smaller than int), integer promotions are applied. The usual arithmetic conversions may also be applied to (implicitly) convert operands to equivalent types before arithmetic operations are performed. Make sure you Programmers should understand integer conversion rules before trying to implement secure arithmetic operations. (See INT02-C. Understand integer conversion rules.)

...

Addition is between two operands of arithmetic type or between a pointer to an object type and an integer type for rules about adding a pointer to an integer. (See ARR37-C. Do not add or subtract an integer to a pointer to a non-array object and ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element.) Incrementing is equivalent to adding 1.

...

This noncompliant code example may result in a signed integer overflow during the addition of the signed operands si_a and si_b. If this behavior is unanticipated, it can lead to an exploitable vulnerability.

Code Block
bgColor#FFcccc
langc
int si_a;
int si_b;
int sum;

/* Initialize si_a and si_b */

sum = si_a + si_b;

...

Subtraction is between two operands of arithmetic type, two pointers to qualified or unqualified versions of compatible object types, or a pointer to an object type and an integer type. See ARR36-C. Do not subtract or compare two pointers that do not refer to the same array, ARR37-C. Do not add or subtract an integer to a pointer to a non-array object, and ARR38-C. Do not add or subtract an integer to a pointer if the resulting value does not refer to a valid array element for information about pointer subtraction. Decrementing is equivalent to subtracting one1.

Noncompliant Code Example

...

Code Block
bgColor#ccccff
langc
signed int si_a;
signed int si_b;
signed int result;

/* Initialize si_a and si_b */

if (((si_a^si_b)
  & (((si_a ^ ((si_a^si_b)
    & (1 << (sizeof(int)*CHAR_BIT-1))))-si_b)^si_b)) < 0) {
  /* Handle error condition */
}
else {
  result = si_a - si_b;
}

This compliant solution works only works on architectures that use two's complement representation. Although most modern platforms use two's complement representation, it is best not to introduce unnecessary platform dependencies. (See MSC14-C. Do not introduce unnecessary platform dependencies.)

...

Code Block
bgColor#ccccff
langc
signed int si_a;
signed int si_b;
signed int result;

/* Initialize si_a and si_b */

if (si_a > 0){  /* si_a is positive */
  if (si_b > 0) {  /* si_a and si_b are positive */
    if (si_a > (INT_MAX / si_b)) {
      /* Handle error condition */
    }
  } /* endEnd if si_a and si_b are positive */
  else { /* si_a positive, si_b non-positivenonpositive */
    if (si_b < (INT_MIN / si_a)) {
        /* Handle error condition */
    }
  } /* si_a positive, si_b non-positivenonpositive */
} /* endEnd if si_a is positive */
else { /* si_a is non-positivenonpositive */
  if (si_b > 0) { /* si_a is non-positivenonpositive, si_b is positive */
    if (si_a < (INT_MIN / si_b)) {
      /* Handle error condition */
    }
  } /* endEnd if si_a is non-positivenonpositive, si_b is positive */
  else { /* si_a and si_b are non-positivenonpositive */
    if ( (si_a != 0) && (si_b < (INT_MAX / si_a))) {
      /* Handle error condition */
    }
  } /* endEnd if si_a and si_b are non-positivenonpositive */
} /* endEnd if si_a is non-positivenonpositive */

result = si_a * si_b;

Anchor
Division
Division

...

This noncompliant code example can result in a signed integer overflow during the division of the signed operands s_a and s_b or in a divide-by-zero error. The IA-32 architecture, for example, requires that both conditions result in a fault, which can easily result in a denial-of-service attack.

Code Block
bgColor#FFcccc
langc
signed long s_a;
signed long s_b;
signed long result;

/* Initialize s_a and s_b */

result = s_a / s_b;

...

On MSVC++, taking the modulo of INT_MIN by −1 yields the value 0. On GCC/Linux, taking the modulo of INT_MIN by −1 produces a floating-point exception. However, on GCC versions 4.2.4 and newer, with optimization enabled, taking the modulo of INT_MIN by −1 yields the value 0.

...

This compliant solution is based on the fact that both the division and modulo operators truncate toward 0, as specified in section subclause 6.5.5, footnote 105, of the C Standard [ISO/IEC 9899:2011]. This , which guarantees that

Code Block
i % j

...

This section includes an example for the addition of atomic integer types only. For other operations, you can use tests similar to the precondition tests for two’s complement integers used for nonatomic integer types can be used.

Noncompliant Code Example

...

Tool

Version

Checker

Description

Coverity6.5TAINTED_STATICFully Implemented

Fortify SCA

5.0

 

Can detect violations of this rule with CERT C Rule Pack. Specifically, it checks to ensure that the operand of a unary negation
is compared to the type's minimum value immediately before the operation

LDRA tool suite

Include Page
LDRA_V
LDRA_V

43 D
493 S
494 S

Partially implemented
PRQA QA-C
Include Page
PRQA_V
PRQA_V

0278
0296
0297
2800

Fully implemented

...

[Dowd 2006]Chapter 6, "C Language Issues" ("Arithmetic Boundary Conditions," pp. 211–223)
[ISO/IEC 9899:2011]Subclause 6.5.5, "Multiplicative Operators"
[Seacord 2013]Chapter 5, "Integer Security"
[Viega 2005]Section 5.2.7, "Integer Overflow"
[VU#551436] 
[Warren 2002]Chapter 2, "Basics"

...