The results of allocating zero bytes of memory using
realloc() are implementation-defined. According to C99 Section 7.20.3 [[ISO/IEC 9899:1999]]:
If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
In cases where the memory allocation functions return a non-null pointer, using this pointer results in undefined behavior. Typically the pointer refers to a zero-length block of memory consisting entirely of control structures. Overwriting these control structures will damage the data structures used by the memory
Noncompliant Code Example (
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 0, 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.
To ensure that zero is never passed as a size argument to
size is checked to ensure it has a positive value.
Noncompliant Code Example
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 a non-null value, 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.
If this noncompliant 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.
This compliant solution does not pass a size argument of zero to the
Allocating zero bytes can lead to abnormal program termination.
Compass/ROSE can some violations of this rule. Is particular, it warns when when the argument to
malloc() is a variable that has not been compared against NULL, or is known at compile time to be 0.
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
This rule appears in the C++ Secure Coding Standard as MEM04-CPP. Do not perform zero length allocations.
[[ISO/IEC 9899:1999]] Section 7.20.3, "Memory Management Functions"
[[MITRE 07]] CWE ID 687, "Function Call With Incorrectly Specified Argument Value"
[[Seacord 05]] Chapter 4, "Dynamic Memory Management"