Buffer overflows are one of those bugs that wreak havoc on embedded software. The system appears to be working perfectly and then all of a sudden, weird things start to happen! Variables that have been behaving suddenly end up with values that are unexpected. Developers often will be stumped and spend days trying to figure out what on Earth is going on, losing precious time and money. In today’s post, I’m going to show you how to identify buffer overflows quickly and efficiently and fix them.
Buffer Overflow Symptoms
A buffer overflow often comes with several symptoms to the system that developers can easily recognize. These symptoms often can be found in variables that appear to have nothing to do with where the overflow is occurring such as:
- Incorrect initialization value
- A changing value without any code acting on the variable
- Out of range values that should be impossible
I was recently working on a project and discovered that a variable I was initializing to true was showing up as false. For a few moments I was quite confused. Was I calling that variable from somewhere else? Nope. Everything looked good, except in the first function it was used in was showing up with the wrong value which completely destroyed the system initial conditions. As you might guess, the cause was a buffer overflow.
Finding Buffer Overflows using Map Files
The problem with buffer overflows is that they can hard to find. Who knows what is overflowing into the variables memory space and corrupting it? Well, the map file knows! If you ever suspect that you have a buffer overflow, there is a simple process you can use to find or rule out the overflow.
- Identify the variable that appears to be corrupted.
- Compile your code.
- Navigate to your compiled project folder and find your Map file.
- Search the map file for the corrupted variable.
- When found, look at what variable is next to your corrupted variable. This is most likely the culprit!
- Search your code for the culprit initialization.
- Increase the buffer size and see if this is indeed the cause.
As I mentioned, I had a variable that was just not behaving right. So, I followed the steps above and in my map file I found the following:
My ScrState variable has a bytesToSend array immediately preceding it in memory! Upon examining this array and the code that uses it, I found that I was overwriting the buffer by 1 byte with the value 0! Just enough to change my ScrState = True variable into a False. (Thankfully this was nothing more than a 2 minute side track!)
Buffer overflows can be tough to find if your process to find them is haphazard. Buffer overflows are often repeatable, which allows the developer to track down what corruption they are causing. A quick search through a map file and identifying the preceding variable(s) can help a developer find the culprit fast and fix their overflow. (There is quite a bit that can be done to prevent this in the first place, but we will save that for another time).