Versions Compared

Key

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

...

The result of calling malloc(0) to allocate 0 bytes is implementation-defined. In this example, a dynamic array of integers is allocated to store size elements. However, if size is zero, the call to malloc(size) may return a reference to a block of memory of size 0 rather than NULL. When data is copied to this location, a heap-buffer overflow occurs.

Code Block
bgColor#FFcccc
size_t size;

/* initialize size, possibly by user-controlled input */

int *list = malloc(size);
if (list == NULL) {
  /* Handle Allocation Error */
}
/* Continue Processing list */

...

To ensure that zero is never passed as a size argument to malloc(), size is checked to ensure it has a positive value.

Code Block
bgColor#ccccff
size_t size;

/* initialize size, possibly by user-controlled input */

if (size <== 0) {
  /* Handle Error */
}
int *list = malloc(size);
if (list == NULL) {
  /* Handle Allocation Error */
}
/* Continue Processing list */

...

If this non-compliant code is compiled with gcc GCC 3.4.6 and linked with libc 2.3.4, invoking realloc(p, 0) returns a non-null pointer to a zero-sized object (the same as malloc(0)). However, if the same code is compiled with either Microsoft Visual Studio Version 7.1 or gcc GCC version 4.1.0 , realloc(p, 0) returns a null pointer, resulting in a double-free vulnerability.

Compliant

...

Solution

This compliant solution does Do not pass a size argument of zero to the realloc() function.

...