Versions Compared

Key

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

...

This compliant solution performs a precondition 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 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 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 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 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;
}

...

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

...

Furthermore, it guarantees that the minimum 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;
}

...

This noncompliant code example using atomic integers can result in unexpected signed integer overflow.:

Code Block
bgColor#FFcccc
langc
atomic_int i;
int si1;

/* Initialize i, si1 */

atomic_fetch_add(&i, si1);

...

This compliant solution tests the operands to guarantee there is no possibility of signed overflow. It loads the value stored in the atomic integer and tests for possible overflow before performing the addition.:

Code Block
bgColor#ccccff
langc
atomic_int i;
int si1;

/* Initialize si1, i */

int si2 = atomic_load(&i);

if (((si2>0) && (si1 > (INT_MAX-si2)))
 || ((si2<0) && (si1 < (INT_MIN-si2)))) {
   /* Handle error condition */
}
else {
  atomic_fetch_add(&i, si1);
}

...

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.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

...