Safeguard
Application Security•

CWE-786 Access of Memory Location Before Start of Buffer

Buffer underflows read or write ahead of the array. Learn how CWE-786 happens through negative indexes and decrementing pointers, and how to stop it.

Safeguard Security Team
3 min read

CWE-786 covers reads and writes that land before the start of a buffer. It is the underflow cousin of the more familiar overflow. It affects memory-unsafe languages, mainly C and C++.

How it happens

MITRE describes the typical triggers: a pointer or index that is decremented past the first element, pointer arithmetic that lands before the buffer, or a negative index.

Examples from the record:

  • CVE-2002-2227: an unchecked length of an SSLv2 challenge value led to a buffer underflow.
  • CVE-2007-4580: a buffer underflow from a small size value used with a large buffer.
  • CVE-2007-1584: an all-whitespace string caused a counter to be decremented before the buffer while the code looked for a non-whitespace character.

That last one is a pattern worth knowing. A loop that trims trailing whitespace walks backward from the end, and when the string is all spaces it never finds a stopping character:

char *end = s + strlen(s) - 1;
while (isspace((unsigned char)*end))   /* no lower bound check */
    end--;
*(end + 1) = '\0';

For an empty or all-space string, end moves before s and the code reads and then writes outside the buffer.

What an attacker gains

The record lists three outcomes. An out-of-bounds read can expose sensitive information. Out-of-bounds access can corrupt memory and crash the program. And if the attacker controls the corrupted memory, code execution may be possible.

How to find it

MITRE recommends fuzzing, which produces many varied inputs and watches for crashes, and automated dynamic analysis that inserts runtime checks at compile time. Add these steps:

  • Build tests with AddressSanitizer enabled.
  • Feed empty, all-whitespace and extreme length inputs.
  • Search code for loops that decrement an index or pointer and ask what stops them at zero.
  • Treat signed values used as indexes with suspicion.

How to fix it

char *end = s + strlen(s);
while (end > s && isspace((unsigned char)end[-1]))
    end--;
*end = '\0';

The fix is a lower-bound check in the loop condition. In general:

  1. Use unsigned types for sizes and validate that a computed index is at least zero before use.
  2. Check lengths against the buffer before pointer arithmetic.
  3. Prefer bounds-checked containers, such as std::vector with at(), or a memory-safe language for new parsing code.
  4. Keep compiler hardening and sanitizers on in test builds.

If you ship C or C++ libraries, outside code depends on yours. The free dependency scan can show whether the packages you ship carry known memory safety issues.

Quick check

How is an underflow different from an overflow?

An overflow goes past the end of the buffer. An underflow goes before the start. Both are out-of-bounds access.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.