...
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 instead of a {{ null
pointer}}. When (nonempty) data is copied to this location, a heap-buffer overflow occurs.
...
The realloc()
function deallocates the old object and returns a pointer to a new object of a specified size. If memory for the new object cannot be allocated, the realloc()
function does not deallocate the old object and its value is unchanged. If the realloc()
function returns NULL, failing to free the original memory will result in a memory leak. As a result, the following idiom is often recommended for reallocating memory:
...
However, this commonly recommended idiom has problems with zero-length allocations. If the value of nsize
in this example is 0, the standard allows the option of either returning a null pointer or returning a pointer to an invalid (e.g., zero-length) object. In cases where the realloc()
function frees the memory but returns a null pointer, execution of the code in this example results in a double free. If the realloc()
function returns non-NULL, but the size was 0, the returned memory will be of size 0, and a heap overflow will occur if nonempty data is copied there.
Implementation Details
If this non-compliant code is compiled with 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 version 4.1.0 , realloc(p, 0)
returns a null pointer, resulting in a double-free vulnerability.
...