C & C++ Dynamic Memory Management
Chapter 4 - Dynamic Memory Management(4.1 - 4.5)
- Book by Robert C. Seacord
This chapter of Book Secure Coding in C And C++ describes dynamic memory management in C and C++ on Linux and Windows platforms. It discusses common dynamic memory management errors, and assesses the corresponding security risks
Buffer Overflow:
- stack (staic memory management)
- heap (dynamic memory management)
C Memory Management
4 memory allocation functions
#include <stdlib.h>
malloc(size_t size)
: aligned to the most strictly aligned object, not initializedaligned_alloc(size_t alignment, size_t size)
: define alignmentrealloc(void *p, size_t size)
: changes the size of the memory block.calloc(size_t nmemb, size_t size)
: set to 0
1 memory deallocation function
free(void *p)
. It frees the memory space pointed to by p, which must have been returned by a previous call toaligned_alloc()
,malloc()
,calloc()
, orrealloc()
.
Free means cancelling the mapping between the pointer and the allocated memory.
Allocated storage duration
- If malloc() is called within a function, the allocated memory will still exist after the function returns.
Alignment
- A fundamental alignment is less than or equal to the greatest alignment supported by the compiler in all contexts. The alignment of the max_align_t type is as great as is supported by a compiler in all contexts.
- If a program requests an alignment that is greater than alignof(max_align_t), the program is not portable because support for an overaligned type is optional.
- A type having an extended alignment requirement is also called an overaligned type.
- If you call the
realloc()
function on a pointer returned from aligned_alloc(), the C Standard does not require that the stricter-than-normal alignment be preserved. This issue is described further by The CERT C Secure Coding Standard [Seacord 2008], “MEM36-C. Check for alignment of memory space before calling realloc() function.”
alloca() and Variable-Length Arrays
- The alloca() function allocates memory in the stack frame of the caller. This memory is automatically freed when the function that called alloca() returns. The alloca() function returns a pointer to the beginning of the allocated space.
- alloca(), which must not be freed. Calling free() on a pointer not obtained by calling a memory allocation function is a serious error and undefined behavior.
Allocation Failure
This will throw an exception:
T* p1 = new T; // throws bad_alloc on failure
Common C Memory Management Errors
- Initialization Errors
- Failing to Check Return Values
- Dereferencing Null or Invalid Pointers
- Referencing Freed Memory
- Freeing Memory Multiple Times
- Memory Leaks
- Zero-Length Alocations
C++ Memory Management
No exception:
T* p2 = new(std::nothrow) T; // returns 0 on failure
Resource Acquisition Is Initialization(RAII)
To keep track of a resource, create an object and associate the resource’s lifetime with the object’s lifetime. This allows you to use C++’s object-management facilities to manage resources.
Deallocation Functions
void operator delete(void *);
void operator delete(void *, size_t);
void operator delete[](void *);
void operator delete[](void *, size_t);
4.4 Common C++ Memory Management Errors
- failing to correctly handle allocation failures
- Incorrect Use of the new Operator
- Improperly Paired Memory Management Functions:
free
withnew
, etc…
1 int *ip = new int(8);
2 ...
3 free(ip); // wrong!
4 ip = static_cast<int *>(malloc(sizeof(int)));
5 *ip = 8;
6 ...
7 delete ip; // wrong!
- Dereferencing null pointers
- Writing to already freed memory
- Freeing the same memory multiple times
- Improperly paired memory management functions
- Failure to distinguish scalars and arrays
- Improper use of allocation functions
Correct Pairing of Memory Allocation and Deallocation functions
Notes:
- C++ uses new and delete to manage memory:
- new and delete for object
- new[] and delete[] for object array
new
will calloperator new
, andoperator new
will callmalloc()
, and the consturct function, and return the pointer.delete
will call destruction function to clear the object, and call operatordelete()
, and therefore thefree()
to free the space.- There will be extra space before
new[x]
thannew
to store the number of the objects, thedelete
will ignore this difference. - It is less dangerous to leak memory than to free the same memory twice.
- Double Free the memory will get the error message:
*** glibc detected *** ./test.out: double free or corruption (fasttop): 0x0000000000970010 ***
Memory Managers
Memory managers manage both allocated and free memory in the heap.
Dynamic storage allocation requires an algorithm for finding and reserving a chunk of n contiguous bytes.
Reference
- Security Coding in C and C++. by Robert C. Seacord. Chapter 4. ISBN-13: 978-0-321-82213-0
- C and C++ Dynamic Memory Management