Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added NCCE of sizeof wrapping and a CS.

...

Code Block
bgColor#FFCCCC
langc
#include <stddef.h>

extern void do_work(int *array, size_t size);
 
void func(size_t size) {
  int vla[size];
  /* ... */do_work(vla, size);
}

However, the value of size may be zero or excessive, potentially giving rise to a security vulnerability.

...

Code Block
bgColor#ccccff
langc
#include <stdint.h>
#include <stdlib.h>
 
enum { MAX_ARRAY = 1024 };
extern void do_work(int *array, size_t size);
 
void func(size_t size) {
  if (0 == size || SIZE_MAX / sizeof(int) < size) {
    /* Handle error */
    return;
  }
  if (size < MAX_ARRAY) {
    int vla[size];
    do_work(vla, size);
  } else {
    int *array = (int *)malloc(size * sizeof(int));
    if (array == NULL) {
      /* Handle error */
    }
    do_work(array, size);
    free(array);
  }
}

Noncompliant Code Example (sizeof)

The following noncompliant code example defines A to be a variable length array type and then uses the sizeof operator to compute its size at runtime.  When the function is called with an argument greater than SIZE_MAX / (N * sizeof (int)), the runtime sizeof expression may wrap around, yielding a result that is smaller than the mathematical product N * n * sizeof (int).  The call to malloc, when successful, will then allocate storage for fewer than n elements of the array, causing one of the final memset calls in the for loop to write past the end of that storage.

Code Block
bgColor#FFCCCC
langc
#include <stdlib.h>
#include <string.h>
 
enum { N = 4096 };

void* func(size_t n) {
  typedef int A [n][N];

  A *array = malloc(sizeof (A));

  for (size_t i = 0; i != n; ++i)
    memset(array [i], 0, N * sizeof (int));

  return array;
}

Compliant Code Solution (sizeof)

This compliant solution prevents sizeof wrapping by detecting the condition before it occurs and avoiding the subsequent computation when the condition is detected.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <string.h>
 
enum { N = 4096 };

void* func(size_t n) {
  if (n > SIZE_MAX / (N * sizeof (int))) {
    /* Prevent sizeof wrapping */
    return NULL;
  }

  typedef int A [n][N];

  A *array = malloc(sizeof (A));
  if (array == NULL) {
    /* Handle malloc failure */
    return NULL;
  } 

  for (size_t i = 0; i != n; ++i)
    memset(array [i], 0, N * sizeof (int));

  return array;
}

Implementation Details

Microsoft

...