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:
freewithnew, 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
newwill calloperator new, andoperator newwill callmalloc(), and the consturct function, and return the pointer.deletewill 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]thannewto store the number of the objects, thedeletewill 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