Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: condensed atomic NCCE/CS into intro paragraph, reviewed

...

GNU GCC invoked without either the -fwrapv or the -ftrapv option may simply assume that signed integers never overflow and may generate object code accordingly. AnchorAdditionAddition

Addition

Addition is between two operands of arithmetic type or between a pointer to an object type and an integer type. This rule only applies to addition between two operands of arithmetic type. See ARR37-C. Do not add or subtract an integer to a pointer to a non-array object and ARR30-C. Do not form or use out of bounds pointers or array subscripts.

Incrementing is equivalent to adding 1.

Noncompliant Code Example

Atomic Integers

The C Standard defines the behavior of arithmetic on atomic signed integer types to use two's complement representation with silent wraparound on overflow; there are no undefined results. However, although defined, these results may be unexpected and therefore carry similar risks to unsigned integer wrapping (see INT30-C. Ensure that unsigned integer operations do not wrap). Consequently, signed integer overflow of atomic integer types should also be prevented or detected. 

 

Anchor
Addition
Addition

Addition

Addition is between two operands of arithmetic type or between a pointer to an object type and an integer type. This rule only applies to addition between two operands of arithmetic type. See ARR37-C. Do not add or subtract an integer to a pointer to a non-array object and ARR30-C. Do not form or use out of bounds pointers or array subscripts.

Incrementing is equivalent to adding 1.

Noncompliant Code Example

This noncompliant code example may result in a signed integer overflow during the addition of the signed operands si_a and si_This noncompliant code example may result in a signed integer overflow during the addition of the signed operands si_a and si_b

Code Block
bgColor#FFcccc
langc
void func(signed int si_a, signed int si_b) {
  signed int sum = si_a + si_b;
  /* ... */
}

...

The C Standard, 6.5.7 paragraph 4 [ISO/IEC 9899:2011], states

...

In almost every case, an attempt to shift by a negative number of bits or by more bits than exist in the operand indicates a bug (logic error). These issues are covered by INT34-C. Do not shift a negative number of bits or more bits than exist in the operand.

Noncompliant Code Example

This noncompliant code example performs a left shift, after verifying that the number being shifted is not negative, and the number of bits to shift is valid.  The PRECISION() macro and popcount() function are explained in INT35-C. Use correct integer precisions. However, because this code does no overflow check, it can result in an unrepresentable value. 

...

Compliant Solution

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

...

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

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
void func(signed long s_a) {
  signed long result;
  if (s_a == LONG_MIN) {
    /* Handle error */
  } else {
    result = -s_a;
  }
  /* ... */
}

Atomic Integers

The C Standard defines the behavior of arithmetic on atomic signed integer types to use two's complement representation with silent wraparound on overflow; there are no undefined results. However, although defined, these results may be unexpected and therefore carry similar risks to unsigned integer wrapping (see INT30-C. Ensure that unsigned integer operations do not wrap). Consequently, signed integer overflow of atomic integer types should also be prevented or detected. 

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

Noncompliant Code Example

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

Code Block
bgColor#FFcccc
langc
#include <stdatomic.h>
 
atomic_int i;

void func(int si_a) {
  atomic_init(&i, 42); 
  atomic_fetch_add(&i, si_a);

  /* ... */
}

Compliant Solution

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. However, this code contains a race condition where i can be modified after the load, but prior to the atomic store. This solution is only compliant if i is guaranteed to only be access by a single thread. See CON08-C. Do not assume that a group of calls to independently atomic methods is atomic for more information.overflow:

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stdatomic.h>
 
atomic_int i;

void func(int si_a) {
  int si_b = atomic_load(&i);

  if (((si_b > 0) && (si_a > (INT_MAX - si_b))) ||
      ((si_b < 0) && (si_a < (INT_MIN - si_b)))) func(signed long s_a) {
  signed long result;
  if (s_a == LONG_MIN) {
    /* Handle error */
  } else {
    atomic_store(&i, si_a + si_b)result = -s_a;
  }

  /* ... */
}


Risk Assessment

Integer overflow can lead to buffer overflows and the execution of arbitrary code by an attacker.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

INT32-C

High

Likely

High

P9

L2

...