Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edits; reviewed

...

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

...

Code Block
bgColor#FFcccc
langc
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int usum;

void func(void) {
  /* Initialize ui_a and ui_b */
  usum = ui_a + ui_b;

 = ui_a + ui_b;

  /* ... */
}

Compliant Solution (Precondition Test)

...

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int usum;

void func(void) {
  /* Initialize ui_a and ui_b */

  if (UINT_MAX - ui_a < ui_b) {
    /* Handle error condition */
  } else {
    usum = ui_a + ui_b;
  }

  /* ... */
}

...

Code Block
bgColor#ccccff
langc
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int usum;

void func(void) {
  /* Initialize ui_a and ui_b */

  usum = = ui_a + ui_b;
  if (usum < ui_a) {
    /* Handle error condition */
  }

  /* ... */
}

...

Subtraction is between two operands of arithmetic type, between two pointers to qualified or unqualified versions of compatible object types, or between 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 ARR38and ARR30-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 subtractionform or use out of bounds pointers or array subscripts for information about pointer subtraction.) Decrementing is equivalent to subtracting 1.

...

Code Block
bgColor#FFcccc
langc
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int udiff;

void func(void) {
  /* Initialize  = ui_a and- ui_b */;

  udiff = ui_a - ui_b;

  //* ... */
}

Compliant Solution (Precondition Test)

...

Code Block
bgColor#ccccff
langc
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int udiff;

void func(void) {
  /* Initialize  if (ui_a and< ui_b */

  if (ui_a < ui_b){
  ){
    /* Handle error condition */
  } else {
    udiff = ui_a - ui_b;
  }

  /* ... */
}

...

Code Block
bgColor#ccccff
langc
void func(unsigned int ui_a;
, unsigned int ui_b;) {
  unsigned int udiff;

void func(void) {
  /* Initialize  = ui_a and- ui_b */

  udiff = ui_a - ui_b;
  if (udiff > ui_a) {
    /* Handle error condition */
  }

  /* ... */
}

...

Code Block
bgColor#ccccff
langc
pen->num_vertices = _cairo_pen_vertices_needed(
  gstate->tolerance, radius, &gstate->ctm
);

if (pen->num_vertices > SIZE_MAX / sizeof(cairo_pen_vertex_t)) {
  /* Handle error condition */
}
pen->vertices = malloc(
  pen->num_vertices * sizeof(cairo_pen_vertex_t)
);

...

Code Block
bgColor#FFcccc
langc
#include <stdatomic.h>
 
atomic_intuint i;
int ui_a;

void func(voidunsigned int a) {
  atomic_init(&i, 42); 
  /* Initialize ui_a */
  atomic_fetch_add(&i, ui_a);
  /* ... */
}

 

Compliant Solution

This compliant solution performs a postcondition test to ensure that the result of the unsigned addition operation to i is not less than the operand ui_a:.  However, this code contains a race condition where i can be modified after the addition, but prior to the atomic load.  This solution is only compliant if i is guaranteed to only be access by a single thread.  See CON43-C. Do not assume that a group of calls to independently atomic methods is atomic for more information.

 

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

void func(unsigned int a) {
 

 

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

void func(void) {
  /* Initialize ui_a, i*/
 
  atomic_fetch_add(&i, ui_a);
  if (atomic_load(&i) < ui_a) {
    /* Handle error condition */
  }
  /* ... */
}

Exceptions

...

A Linux kernel vmsplice exploit, described by Rafal Wojtczuk [Wojtczuk 2008], documents a vulnerability and exploit arising from a buffer overflow (caused by unsigned integer wrapping).

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

Related Guidelines

integer wrapping).

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

Related Guidelines

...

[Dowd 2006]Chapter 6, "C Language Issues" ("Arithmetic Boundary Conditions," pp. 211–223)
[ISO/IEC 9899:2011]Subclause 6.2.5, "Types"
[Seacord 2013]Chapter 5, "Integer Security"
[Viega 2005]Section 5.2.7, "Integer Overflow"
[VU#551436] 
[Warren 2002]Chapter 2, "Basics"
[Wojtczuk 2008] 
[xorl 2009]"CVE-2009-1385: Linux Kernel E1000 Integer Underflow"

 

...