Safeguard
Application Security•

CWE-131 Incorrect Calculation of Buffer Size: Causes and Fixes

Wrong buffer size math is behind many heap overflows. See the integer and encoding mistakes that cause CWE-131 and how to calculate sizes safely.

Safeguard Security Team
5 min read

CWE-131, Incorrect Calculation of Buffer Size, applies when the product does not correctly calculate the size to use when allocating a buffer, which could lead to a buffer overflow. The copy code is fine. The allocation before it was too small.

MITRE lists C and C++ as the platforms. If you allocate memory using sizes that come from input, from arithmetic, or from string lengths, this weakness is worth a careful look.

How it happens

Buffer size math goes wrong in a handful of ways, and MITRE's observed examples cover most of them.

  • Integer overflow or wraparound. CVE-2025-46687: a JavaScript engine does not perform a length check, an integer overflow causes a smaller buffer to be allocated than expected, and a heap-based overflow results.
  • Sign and width mistakes. CVE-2025-27363: a font rendering library mishandles assigning a signed short to an unsigned long, leading to an integer wraparound and a buffer that is too small. CVE-2020-17087: integer truncation causes a small buffer allocation, leading to an out-of-bounds write in the kernel pool, exploited in the wild per CISA KEV.
  • Size checked before the string grows. CVE-2004-1363: a substitution overflow where environment variables are expanded after the length check was performed.

Other common causes are forgetting the terminating NUL byte, counting characters when bytes are needed, and multiplying a count by an element size without checking the product.

// Vulnerable: forgets the terminator, and count * size can wrap
char *dup_name(const char *s) {
    char *p = malloc(strlen(s));          // needs strlen(s) + 1
    strcpy(p, s);                          // writes one byte too many
    return p;
}

int *make_table(uint32_t n) {
    return malloc(n * sizeof(int));        // n * 4 can wrap on 32-bit size_t
}
// Fixed
char *dup_name(const char *s) {
    size_t n = strlen(s) + 1;
    char *p = malloc(n);
    if (!p) return NULL;
    memcpy(p, s, n);
    return p;
}

int *make_table(size_t n) {
    if (n > SIZE_MAX / sizeof(int)) return NULL;
    return malloc(n * sizeof(int));
}

Related entries are CWE-190 for integer overflow and CWE-122 for the heap overflow that follows.

What an attacker gains

MITRE says that if the incorrect calculation feeds memory allocation, the software may create a buffer smaller or larger than expected. If the allocated buffer is smaller, the program can overflow it. Listed consequences:

  • Crashes.
  • Code execution. Arbitrary code or commands may run.
  • Memory reads and writes. The attacker may read or modify memory beyond the intended buffer.

The kernel pool example above shows how far this can go. A single truncated size in privileged code can turn into a write primitive.

How to find it

MITRE names these methods.

  1. Static analysis. Data flow and constraint-based tools can often find it, though they may miss environment-dependent cases.
  2. Dynamic testing and fuzzing. Large and diverse inputs, stress testing and fault injection.
  3. Compiler runtime checks. AddressSanitizer for C and C++, which needs crafted inputs to reach the faulty code.
  4. Manual analysis. Useful, but it may not give enough coverage in limited time, especially when the weakness depends on a specific input.

When reviewing, look at every allocation call and ask three questions. Where does the size come from? Can the arithmetic wrap or truncate? Is the copy bound taken from the same variable?

How to fix it

The record has no mitigation list. These steps come from the causes.

  1. Calculate sizes in a type wide enough to hold the result, such as size_t.
  2. Check multiplication and addition for overflow before allocating, using checked arithmetic helpers.
  3. Add one byte for string terminators, and count bytes not characters when encodings are multi-byte.
  4. Use one variable for both allocation and copy size.
  5. Re-check size after any step that grows the data, such as expansion or substitution.
  6. Reject inputs whose declared sizes exceed a defined maximum.

Fixes reach you through updates

Most size calculation bugs you will meet are in libraries: JavaScript engines, font renderers, kernels. Your job is often to know you ship the component and to pick up the fix quickly. A tool that shows which vulnerabilities already have a fixed version available turns that into a short list.

Click through it at your own pace, or open it full screen.

To see what is in your own manifest, try the free in-browser dependency scan. No login, the file stays on your machine, and it handles up to 100 dependencies.

Quick check

Why is forgetting the NUL terminator a CWE-131 issue?

The allocation is one byte smaller than the data that will be copied, so the final byte lands outside the buffer.

How does an integer bug become a heap overflow?

The arithmetic wraps or truncates, so malloc returns a small block. The copy still uses the original large count, and it writes past the allocation.

Where should the size checks happen?

Before the allocation, and again after any step that changes the size of the data, such as expanding variables in a string.

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.