Incorrect Calculation of Buffer Size

Description

Incorrect Calculation of Buffer Size occurs when a program allocates a buffer but incorrectly calculates its required size, leading to a buffer that is too small for the data it needs to hold. Common causes include off-by-one errors (forgetting NULL terminators), integer overflow in size calculations, signed/unsigned confusion, incorrect assumptions about data encoding sizes (UTF-8 vs UTF-16), and failure to account for data expansion during processing. When subsequent operations use the originally intended (larger) size, buffer overflows occur.

Risk

Incorrect buffer size calculations are highly exploitable and have enabled numerous remote code execution vulnerabilities. Integer overflow in size calculations is particularly dangerous: multiplying large user-controlled values can wrap to small values, resulting in tiny allocations that are massively overflowed. This vulnerability class affects all software that performs dynamic memory allocation, particularly network services parsing variable-length data, image processors handling dimensions, and compression libraries. Exploitation typically leads to heap corruption and arbitrary code execution.

Solution

Always verify arithmetic operations used in size calculations for potential overflow. Check that multiplication results don't exceed SIZE_MAX before allocation. Account for NULL terminators, padding, and alignment requirements. Use safe allocation patterns that validate sizes. Consider using calloc() for multiplication as it may detect overflow. Use compiler flags like -ftrapv to detect signed overflow. Apply static analysis to identify calculation errors. Prefer high-level languages or safe abstractions that handle allocation automatically.

Common Consequences

ImpactDetails
IntegrityScope: Memory Corruption

Undersized buffers are overflowed during data operations, corrupting heap metadata and adjacent allocations.
Access ControlScope: Code Execution

Heap corruption from undersized buffers enables arbitrary code execution through heap exploitation techniques.
AvailabilityScope: Denial of Service

Memory corruption commonly causes crashes; integer overflow in allocation can cause resource exhaustion.

Example Code + Solution Code

Vulnerable Code

#include <stdlib.h>
#include <string.h>

// VULNERABLE: Off-by-one - forgets NULL terminator
char *copy_string_wrong(const char *src) {
    size_t len = strlen(src);
    char *dst = malloc(len);  // Should be len + 1

    strcpy(dst, src);  // Writes NULL byte beyond allocation
    return dst;
}

// VULNERABLE: Integer overflow in multiplication
void *allocate_matrix(unsigned int rows, unsigned int cols) {
    // If rows * cols overflows, allocates tiny buffer
    size_t size = rows * cols * sizeof(int);

    int *matrix = malloc(size);

    // Loop uses original row/col values - massive overflow
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            matrix[i * cols + j] = 0;
        }
    }
    return matrix;
}

// VULNERABLE: Signed/unsigned confusion
void *allocate_items(int num_items) {
    // If num_items is negative, calculation produces wrong result
    // When cast to size_t, becomes huge value
    size_t size = num_items * sizeof(Item);

    return malloc(size);  // May fail or allocate enormous buffer
}

Fixed Code

#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>

// SAFE: Account for NULL terminator
char *copy_string_safe(const char *src) {
    size_t len = strlen(src);

    // Check for overflow when adding 1
    if (len == SIZE_MAX) {
        return NULL;
    }

    char *dst = malloc(len + 1);  // Include NULL terminator
    if (dst) {
        memcpy(dst, src, len);
        dst[len] = '\0';
    }
    return dst;
}

// SAFE: Check for multiplication overflow
void *allocate_matrix_safe(size_t rows, size_t cols) {
    // Check for overflow in rows * cols
    if (rows != 0 && cols > SIZE_MAX / rows) {
        return NULL;  // Would overflow
    }

    size_t num_elements = rows * cols;

    // Check for overflow in num_elements * sizeof(int)
    if (num_elements > SIZE_MAX / sizeof(int)) {
        return NULL;  // Would overflow
    }

    size_t size = num_elements * sizeof(int);

    int *matrix = calloc(num_elements, sizeof(int));
    return matrix;
}

// SAFE: Use calloc for overflow-checked allocation
void *allocate_items_safe(size_t num_items) {
    // Reject unreasonable sizes
    if (num_items > MAX_ITEMS) {
        return NULL;
    }

    // calloc may detect overflow in multiplication
    return calloc(num_items, sizeof(Item));
}

// SAFE: Comprehensive size check function
bool safe_multiply_size(size_t a, size_t b, size_t *result) {
    if (a != 0 && b > SIZE_MAX / a) {
        return false;  // Overflow
    }
    *result = a * b;
    return true;
}

Exploited in the Wild

Qualcomm Chipset Vulnerabilities (Mobile Devices, 2025)

Multiple high-severity buffer size calculation vulnerabilities in Qualcomm chipsets affecting Android devices, enabling potential code execution on millions of mobile devices.

Schneider Electric Modicon PLCs (Industrial Control, 2025)

CVE affecting Schneider Electric Modicon M580 PLCs with incorrect buffer size calculation, enabling denial of service attacks on critical industrial infrastructure.

Google Android Media Processing (Android, Multiple)

Multiple buffer size calculation vulnerabilities in Android media processing components have enabled remote code execution through malicious media files.


Tools to test/exploit

  • AddressSanitizer — detects buffer overflows from undersized allocations.

  • Coverity — static analysis identifying buffer size calculation errors.

  • AFL++ — fuzzer effective at triggering size calculation bugs.


CVE Examples


References

  1. MITRE. "CWE-131: Incorrect Calculation of Buffer Size." https://cwe.mitre.org/data/definitions/131.html

  2. CERT. "MEM35-C. Allocate sufficient memory for an object." https://wiki.sei.cmu.edu/confluence/display/c/MEM35-C