Versions Compared

Key

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

Integer overflow is undefined behavior. This means that implementations have a great deal of latitude in how they deal with signed integer overflow. An implementation that defines signed integer types as being modulo, for example, does need not detect integer overflow. Implementations may also trap on signed arithmetic overflows, or simply assume that overflows will never happen and generate object code accordingly (see MSC15-C. Do not depend on undefined behavior). For these reasons, it is important to ensure that operations on signed integers do no result in signed overflow. Of particular importance, however, are operations on signed integer values that originate from untrusted sources and are used in any of the following ways:

  • as an array index
  • in any pointer arithmetic
  • as a length or size of an object
  • as the bound of an array (for example, a loop counter)
  • as an argument to a memory allocation function
  • in security-critical code

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:

...

Code Block
bgColor#FFcccc
int si1, si2, sum;

/* Initialize si1 and si2 */

sum = si1 + si2;

Compliant Solution (Two's Complement)

...

Code Block
bgColor#ccccff
signed int si1, si2, sum;

/* Initialize si1 and si2 */

if ( ((si1^si2) 
   | (((si1^(~(si1^si2) 
     & (1 << (sizeof(int)*CHAR_BIT-1))))+si2)^si2)) >= 0) 
{
   /* handle error condition */
}
else {
  sum = si1 + si2;
}

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

...

Code Block
bgColor#ccccff
signed int si1, si2, sum;

/* Initialize si1 and si2 */

if (((si1>0) && (si2>0) && (si1 > (INT_MAX-si2))) 
 || ((si1<0) && (si2<0) && (si1 < (INT_MIN-si2)))) 
{
   /* handle error condition */
}
else {
  sum = si1 + si2;
}

This solution is more readable but contains branches and consequently may be less efficient than the solution that is specific to two's complement representation.

...

Code Block
bgColor#FFcccc
signed int si1, si2, result;

/* Initialize si1 and si2 */

result = si1 - si2;

Compliant Solution (Two's Complement)

...

Code Block
bgColor#ccccff
signed int si1, si2, result;

/* Initialize si1 and si2 */

if (((si1^si2) 
  & (((si1 ^ ((si1^si2) 
    & (1 << (sizeof(int)*CHAR_BIT-1))))-si2)^si2)) < 0) 
{
  /* handle error condition */
}
else {
  result = si1 - si2;
}

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

...

Code Block
bgColor#FFcccc
signed int si1, si2, result;

/* ... */

result = si1 * si2;

Compliant Solution

...

Code Block
bgColor#ccccff
signed int si1, si2, result;
static_assert(
/* Initialize si1 and si2 */

static_assert(
  sizeof(long long) >= 2 * sizeof(int), 
  "Unable to detect overflow after multiplication"
);

signed long long tmp 
  = (signed long long)si1 * 
                       (signed long long)si2;

/*
 * If the product cannot be represented as a 32-bit integer, 
 * handle as an error condition.
 */
if ( (tmp > INT_MAX) || (tmp < INT_MIN) ) {
  /* handle error condition */
}
else {
  result = (int)tmp;
}

The compliant solution uses a static assertion to ensure that the overflow detection will succeed. See DCL03-C. Use a static assertion to test the value of a constant expression for a discussion of static assertions.

...

Code Block
bgColor#ccccff
signed int si1, si2, result;

/* Initialize si1 and si2 */

if (si1 > 0){  /* si1 is positive */
  if (si2 > 0) {  /* si1 and si2 are positive */
    if (si1 > (INT_MAX / si2)) {
      /* handle error condition */
    }
  } /* end if si1 and si2 are positive */
  else { /* si1 positive, si2 non-positive */
    if (si2 < (INT_MIN / si1)) {
        /* handle error condition */
    }
  } /* si1 positive, si2 non-positive */
} /* end if si1 is positive */
else { /* si1 is non-positive */
  if (si2 > 0) { /* si1 is non-positive, si2 is positive */
    if (si1 < (INT_MIN / si2)) {
      /* handle error condition */
    }
  } /* end if si1 is non-positive, si2 is positive */
  else { /* si1 and si2 are non-positive */
    if ( (si1 != 0) && (si2 < (INT_MAX / si1))) {
      /* handle error condition */
    }
  } /* end if si1 and si2 are non-positive */
} /* end if si1 is non-positive */

result = si1 * si2;

...

Division is between two operands of arithmetic type. Overflow can occur during two's-complement signed integer division when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to -1—1. Division operations are also susceptible to divide-by-zero errors (see INT33-C. Ensure that division and modulo operations do not result in divide-by-zero errors).

...

Code Block
bgColor#FFcccc
signed long sl1, sl2, result;

/* Initialize sl1 and sl2 */

result = sl1 / sl2;

Compliant Solution

...

Code Block
bgColorccccff
signed long sl1, sl2, sl1,result;

/* Initialize sl1 and sl2, result;*/

if ( (sl2 == 0) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
  /* handle error condition */
}
else {
  result = sl1 / sl2;
}

Anchor
Modulo
Modulo

Modulo

The modulo operator provides the remainder when two operands of integer type are divided.

...

This code can result in a divide-by-zero or an overflow error during the modulo operation on the signed operands sl1 and sl2. Overflow can occur during a modulo operation when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to -1—1.

Code Block
bgColor#FFcccc
signed long sl1, sl2, result;

result = sl1 % sl2;

...

Code Block
bgColor#ccccff
signed long sl1, sl2, result;

/* Initialize sl1 and sl2 */

if ( (sl2 == 0 ) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
  /* handle error condition */
}
else {
  result = sl1 % sl2;
}

Anchor
Unary Negation
Unary Negation

...

The unary negation operator takes an operand of arithmetic type. Overflow can occur during two's - complement unary negation when the operand is equal to the minimum (negative) value for the signed integer type.

...

Code Block
bgColor#FFcccc
signed int si1, result;

/* Initialize si1 */

result = -si1;

Compliant Solution

...

Code Block
bgColorccccff
signed int si1, result;;

/* Initialize si1 */

if (si1 == INT_MIN) {
  /* handle error condition */
}
else 
  result = -si1;
}

Anchor
Left Shift Operator
Left Shift Operator

Left-Shift Operator

The left-shift operator is between two operands of integer type.

...

Code Block
bgColor#FFcccc
int si1, si2, sresult;

/* Initialize si1 and si2 */

sresult = si1 << si2;

Compliant Solution

This compliant solution eliminates the possibility of overflow resulting from a left-shift operation.

Code Block
bgColor#ccccff
int si1, si2, sresult;

/* Initialize si1 and si2 */

if ( (si1 < 0) 
  || (si2 < 0) ||
    || (si2 >= sizeof(int)*CHAR_BIT) ||
    || (si1 > (INT_MAX >> si2)) 
) 
{
  /* handle error condition */
}
else {
  sresult = si1 << si2;
}

...

Wiki Markup
\[[Dowd 06|AA. C References#Dowd 06]\] Chapter 6, "C Language Issues" (Arithmetic Boundary Conditions, pp. 211-223)
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.5, "Expressions," and Section 7.10, "Sizes of integer types <limits.h>"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "XYY Wrap-around Error"
\[[MITRE 07|AA. C References#MITRE 07]\] [CWE ID 129|http://cwe.mitre.org/data/definitions/129.html], "Unchecked Array Indexing"; and [CWE ID 190|http://cwe.mitre.org/data/definitions/190.html], "Integer Overflow (Wrap or Wraparound)"
\[[Seacord 05|AA. C References#Seacord 05]\] Chapter 5, "Integers"
\[[Viega 05|AA. C References#Viega 05]\] Section 5.2.7, "Integer overflow"
\[[VU#551436|AA. C References#VU551436]\]
\[[Warren 02|AA. C References#Warren 02]\] Chapter 2, "Basics"

...