Versions Compared

Key

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

...

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

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

/* Initialize si1 and si2 */

sum = si1 + si2;

...

This compliant solution performs a pre-condition test of the operands of the addition to ensure no overflow occurs, assuming two's complement representation.

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

/* Initialize si1 and si2 */

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

...

This compliant solution tests the suspect addition operation to ensure no overflow occurs regardless of representation.

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

/* Initialize si1 and si2 */

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

...

This noncompliant code example can result in a signed integer overflow during the subtraction of the signed operands si1 and si2. If this behavior is unanticipated, the resulting value may be used to allocate insufficient memory for a subsequent operation or in some other manner that can lead to an exploitable vulnerability.

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

/* Initialize si1 and si2 */

result = si1 - si2;

...

This compliant solution tests the operands of the subtraction to guarantee there is no possibility of signed overflow, presuming two's complement representation.

Code Block
bgColor#ccccff
langc
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 tests the operands of the subtraction to guarantee there is no possibility of signed overflow, regardless of representation.

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

/* Initialize si1 and si2 */

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

...

This noncompliant code example can result in a signed integer overflow during the multiplication of the signed operands si1 and si2. If this behavior is unanticipated, the resulting value may be used to allocate insufficient memory for a subsequent operation or in some other manner that can lead to an exploitable vulnerability.

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

/* ... */

result = si1 * si2;

...

This compliant solution guarantees there is no possibility of signed overflow on systems where long long is at least twice the size of int.

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

/* 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;
}

...

On systems where this relationship does not exist, the following compliant solution may be used to ensure signed overflow does not occur.

Code Block
bgColor#ccccff
langc
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;

...

This noncompliant code example can result in a signed integer overflow during the division of the signed operands sl1 and sl2 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 sl1, sl2, result;

/* Initialize sl1 and sl2 */

result = sl1 / sl2;

...

This compliant solution guarantees there is no possibility of signed overflow or divide-by-zero errors.

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

/* Initialize sl1 and sl2 */

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

...

This noncompliant code example can result in a divide-by-zero error. Furthermore, many hardware platforms implement modulo as part of the division operator, which can overflow. 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. This occurs in spite of the fact that the result of such a modulo operation should theoretically be 0.

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

result = sl1 % sl2;

...

This compliant solution tests the modulo operand to guarantee there is no possibility of a divide-by-zero error or an (internal) overflow error.

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

/* Initialize sl1 and sl2 */

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

...

Furthermore, it guarantees that the minumum signed value modulo -1 yields 0.

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

/* Initialize sl1 and sl2 */

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

...

This noncompliant code example can result in a signed integer overflow during the unary negation of the signed operand si1.

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

/* Initialize si1 */

result = -si1;

...

This compliant solution tests the suspect negation operation to guarantee there is no possibility of signed overflow.

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

/* Initialize si1 */

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

...

This noncompliant code example can result in signed integer overflow.

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

/* Initialize si1 and si2 */

sresult = si1 << si2;

...

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

Code Block
bgColor#ccccff
langc
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;
}

...