Click here to Skip to main content
Click here to Skip to main content
Go to top

Secure Coding Best Practices for Memory Allocation in C and C++

, 17 May 2006
Rate this:
Please Sign up or sign in to vote.
Straight-to-the-point reckoner for avoiding security issues when allocating memory in C and C++ by Richard Lewis

Introduction

Tomes (and I'm talking of real big tomes) are available on secure coding in C and C++. They describe the details of the language, why C, C++ are so insecure and coding patterns and anti-patterns. They tell you what to chew and what to eschew. At the end of it all - when you come down to writing code - how many of these best practices do you remember?

The answer to the above questions is best left to your judgement. In this secure programming series, I intend to bring before you collections of programming best practices collected from the following sources:

  1. My own experience and the invaluable experience that I have obtained when reviewing source code.
  2. Numerous books available on the topic (my favourite being Secure Programming in C and C++ by Robert Seacord). I recently picked up Exceptional C++ and More Exceptional C++ by Herb Sutter and wonder how I did without these ones!

This article gives you tips to follow when allocating and deallocating memory in C and C++. If your code does not follow them, then you run a risk of making your programs susceptible to all types of attacks (describing the attacks does not fall in the scope of the article).

Without wasting any more of your time (or mine), let us dig in.

Secure Memory Allocation Tips Common to C and C++

Tip 1

Use static buffers wherever possible. The compiler automatically frees such memory.

Tip 2

Previously allocated memory should be manually freed, after it is no longer required.

Don't laugh, meet someone who's making a switch from Java into C, C++ and you'll know what I'm talking about.

Tip 3

Given an option to choose between calloc/malloc or new to allocate memory, go in for the latter - use new, don't use calloc/malloc.

Tip 4

When using C and C++ code together, if new has been used to allocate memory, use delete to free it. Do not use free. Likewise, if malloc or calloc has been used to allocate memory, use free when deallocating. Do not use delete.

Unfortunately, many programmers feel they can get away with using free when allocation has been done by new (and vice versa) because they discovered while debugging that new was implemented using malloc and that delete was implemented using free! Don't fall in this trap.

Tip 5

Often a function requires to set a buffer supplied by the caller. The length of the buffer may be unknown to the caller so the caller may not know how much memory to allocate before supplying that buffer to the function. In such cases, the function should provide a means for the caller to determine how many bytes are required to be allocated.

A common way to do this is by allowing the caller to call the function with a special argument so that it will return the number of bytes the caller must allocate for the buffer.

Tip 6

When shipping code libraries (or SDKs as they are called), provide wrapper functions that encapsulate new and delete. This helps prevent single-threaded and multi-threaded runtime issues.

Tip 7

Use unsigned integer types to hold the number of bytes to be allocated, when allocating memory dynamically. This weeds out negative numbers. Also check the length of memory allocated against a maximum value.

Tip 8

Do not allocate and deallocate memory in a loop as this may slow down the program and may sometime cause security malfunctions.

Tip 9

Assign NULL to a pointer after freeing (or deleting) it. This prevents the program from crashing should the pointer be accidentally freed again. Calling free or delete on NULL pointers is guaranteed not to cause a problem.

Tip 10

Compilers are known to vaporise calls to memset() that appear after all modifications to the memory location is complete for that flow. Use SecureZeroMemory() to prevent this from happening.

Tip 11

When storing secrets such as passwords in memory, overwrite them with random data before deleting them. Need to note that free and delete merely make previously allocated memory unavailable, they don't really 'delete' data contained in that memory.

Tip 12

An easy way to find out if your code is leaking memory is by executing it and examining its memory usage either using Task Manager on Windows or top on Linux.

Secure Memory Allocation Tips in C

Tip 1

Ensure that 0 (zero) bytes are not allocated using malloc. According to the documentation, behaviour for malloc() for this case is undefined.

Tip 2

Always check the pointer to the memory returned by calloc/malloc. If this pointer turn out to be NULL, the memory allocation should be considered unsuccessful and no operations should be performed using that pointer.

Tip 3

When allocating an array of objects, remember to free the array in a loop.

Tip 4

Do not use realloc when allocating buffers that will store sensitive data in them. The implementation of realloc copies and moves around the data based on your reallocations. This implies that your sensitive data ends up in several other areas in memory which you would have no means of "scrubbing".

Secure Memory Allocation Tips in C++

Tip 1

When allocating collections use...

std::vector<thing> vt(100,thing());

rather than:

thing* pt = new thing[100];

The vector defined above is clearly defined on the stack and therefore memory deallocation will be handled by the compiler. If the storage needs a longer lifetime, say as part of a larger class instance, then make it a member variable and initialize the storage with assign() when required.

Tip 2

When using new to allocate an array of objects, use the delete [ ] convention when freeing memory. Using delete without the subscript operator [ ] will result in a memory leak.

Tip 3

Use auto_ptr more often than you currently do when allocating so that deallocation is handled automatically. Remember the following guidelines when dealing with auto_ptrs.

  • An existing non-const auto_ptr can be reassigned to own a different object by using its reset() function.
  • The auto_ptr::reset() function deletes the existing owned object before owning the new one.
  • Only one auto_ptr can own an object. So after one auto_ptr (say, P1) has been assigned to another auto_ptr (say, P2) do not use P1 any longer to call a method on the object as P1 is reset to NULL. Remember that the copy of an auto_ptr is not equivalent to the original.
  • Do not put auto_ptrs into standard containers. This is because doing this creates a copy of the auto_ptr and as mentioned above, the copy of an auto_ptr is not equivalent to the original.
  • Dereferencing an auto_ptr is the only allowed operation on a const auto_ptr.
  • auto_ptr cannot be used to manage arrays.

Tip 4

When using new, enclose it within a try-catch block. The new operator throws an exception and does not return a value. To force the new operator to return a value, use the nothrow qualifier as shown below:

thing * pt = new (std::nothrow) thing[100]; 

Finally...

I hope you enjoyed reading these tips. If you did, please vote and rate this article below. I shall wait for your comments and feedback. I will collate comments from all of you and update the article - not to mention - and give you all credits. Please feel free to email me at richiehere@hotmail.com. Good luck and secure programming!

Revision History

Thanks to Jerry Evans, Ogrig, Mauro H. Leggieri, SilentSilent, Darka, Rob Hemstede and Peterchen for their quality comments and reviews that influenced the previous versions of this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Richard Lewis
Web Developer
India India
I am a Software Security Consultant and specialize in secure code and design reviews. It is my career ambition to build a security fabric for secure software development. I have a programming background in C, C++, device drivers and MFC. I have done a couple of PKI deployments and have also developed a desktop encryptor, authentication SDK and cryptographic SDK.
 
I believe I am what I am because I choose God to make me what He wants me to be.

Comments and Discussions

 
GeneralMy vote of 4 Pinmemberbloodelf0221-Dec-11 20:50 
GeneralTip 1 PinmemberNeil_Scales19-May-06 4:36 
GeneralTip 7 - size_t PinmemberNeil_Scales19-May-06 4:33 
GeneralArticle revised PinmemberRichard Lewis20-Apr-06 19:50 
GeneralC++ != C PinmemberJerry Evans20-Apr-06 13:31 
GeneralTip 11 PinmemberJörgen Sigvardsson20-Apr-06 13:12 
GeneralRe: Tip 11 Pinmemberogrig20-Apr-06 13:56 
GeneralRe: Tip 11 Pinmembertechnomanceraus1-May-06 19:19 
GeneralRe: Tip 11 Pinmemberogrig1-May-06 19:43 
You are right, NULL is just a #define and not part of the language.
 
But due to the C heritage and its usage in the Windows API pretty much everybody uses it interchangeably. At least I do.
 
There is an interesting discussion of what NULL is, isn't and where it can harm you in the Scott Meyers' Effective C++, but I never had any issues with it. Maybe I never had to write anything complex enough Smile | :)

 
OGR
GeneralRe: Tip 11 PinmemberRichard Lewis2-May-06 0:09 
GeneralTip 5 PinmemberMauro Leggieri20-Apr-06 6:12 
GeneralRe: Tip 5 Pinmemberogrig20-Apr-06 13:32 
GeneralRe: Tip 5 PinmemberMauro Leggieri18-May-06 2:21 
GeneralTip 13 :-D PinmemberSilentSilent20-Apr-06 3:30 
GeneralRe: Tip 13 :-D PinmemberDarka20-Apr-06 3:52 
GeneralRe: Tip 13 :-D Pinmemberogrig20-Apr-06 13:08 
GeneralRe: Tip 13 :-D PinmemberDarka20-Apr-06 21:06 
GeneralRe: Tip 13 :-D PinmemberRichard Lewis20-Apr-06 5:39 
GeneralRe: Tip 13 :-D PinmemberRob Hemstede20-Apr-06 9:45 
GeneralRe: Tip 13 :-D Pinmemberogrig20-Apr-06 13:26 
AnswerRe: Tip 13 :-D PinmemberSilentSilent20-Apr-06 22:13 
GeneralRe: Tip 13 :-D PinmemberRichard Lewis20-Apr-06 22:47 
Generalinstead of auto_ptr... Pinmemberpeterchen20-Apr-06 2:05 
GeneralRe: instead of auto_ptr... PinmemberRichard Lewis20-Apr-06 2:47 
GeneralUseful article PinmemberDarka20-Apr-06 0:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140922.1 | Last Updated 18 May 2006
Article Copyright 2006 by Richard Lewis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid