Richard Reese

Memory Deallocation Issues in C

Handle sensitive data, free memory, and more

It may seem that when dynamic memory has been deallocated, we are done with it. We have avoided a memory leak and can confidently move on to other issues. In some cases this may be the case. However, we may need to be concerned with issues such as how we handle sensitive data and whether we need to even worry about freeing memory if the application is about to terminate. In this discussion we will examine these issues and others.

The Heap and System Memory

The heap typically uses operating system functions to manage its memory. The heap’s size may be fixed when the program is created, or it may be allowed to grow. However, the heap manager does not necessarily return memory to the operating system when the free function is called. The deallocated memory is simply made available for subsequent use by the application. Thus, when a program allocates and then frees up memory, the deallocation of memory is not normally reflected in the application’s memory usage as seen from the operating system perspective.

Double Free

Memory is typically deallocated using the free function. One concern deals with what happens when we try to free the same memory twice. Freeing a block of memory twice is referred to as double free. The following illustrates how this can be done:

char *name = (char*)malloc(...);

...

free(name);     // First free

...

free(name);     // Double free

More subtle occurrences of double free occur when pointers are aliased:

char *name = (char*)malloc(...);

char *tmp = name;

...

free(name);     // First free

...

free(tmp);     // Double free

In an earlier version of the zlib compression library, it was possible for a double-free operation to result in a denial of service attack or possibly to insert code into the program. However, this is extremely unlikely and the vulnerability has been addressed in newer releases of the library. More information about this vulnerability can be found at cert.org.

A simple technique to avoid this type of vulnerability is to always assign NULL to a pointer after it has been freed. Subsequent attempts to free a null pointer will be ignored by most heap managers.

char *name = (char*)malloc(...);

...

free(name);

name = NULL;

Read more…