Buffer Underwrite ('Buffer Underflow')

Description

Buffer Underwrite (also known as Buffer Underflow) occurs when a program writes to memory locations before the beginning of an allocated buffer. This typically happens when pointer arithmetic or array indexing produces a value that references memory preceding the buffer's start address. Common causes include decrementing pointers beyond buffer boundaries, using negative array indices, or integer underflows in index calculations. Buffer underwrites can corrupt memory structures located before the target buffer, including heap metadata, other variables, or control structures.

Risk

Buffer underwrites are dangerous because they can corrupt critical data structures that precede the target buffer in memory. In heap allocations, this may corrupt heap metadata of previous chunks, enabling exploitation through heap management functions. On the stack, underwrites can corrupt saved registers, return addresses, or local variables of calling functions. While less common than buffer overflows, underwrites can be equally devastating when exploitable. The corruption of preceding data structures often leads to exploitation scenarios similar to use-after-free or arbitrary write conditions.

Solution

Always validate array indices and pointer arithmetic to ensure they remain within valid buffer bounds. Check for both upper and lower boundary violations. Use unsigned integer types for array indices where negative values are invalid. Implement safe buffer access functions that verify bounds in both directions. Use memory-safe languages or C++ containers that prevent out-of-bounds access. Enable AddressSanitizer during development to detect underwrites. Conduct code review focusing on pointer arithmetic operations, especially those involving subtraction or negative offsets.

Common Consequences

ImpactDetails
IntegrityScope: Integrity

Memory preceding the buffer is corrupted, potentially including heap metadata, other variables, or control structures.
Access ControlScope: Code Execution

If attacker controls the underwrite offset and value, arbitrary code execution may be achieved through corrupted function pointers or heap metadata.
AvailabilityScope: Availability

Corrupted memory structures typically cause crashes during subsequent memory operations.

Example Code + Solution Code

Vulnerable Code

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

// VULNERABLE: Negative index underwrite
void process_data(int *data, int index, int value) {
    // No check for negative index
    data[index] = value;  // Underwrite if index < 0
}

// VULNERABLE: Pointer arithmetic underflow
void copy_reversed(char *dest, char *src, size_t len) {
    char *end = src + len - 1;

    // Bug: loop continues past beginning of buffer
    while (end >= src - 10) {  // Off-by-many error
        *dest++ = *end--;       // Reads before src buffer
    }
}

// VULNERABLE: Integer underflow in index calculation
void write_at_offset(char *buffer, unsigned int user_offset, char value) {
    // user_offset is unsigned but subtraction can underflow
    int index = user_offset - 100;  // Underflows if user_offset < 100
    buffer[index] = value;          // Large negative index
}

Fixed Code

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

// SAFE: Bounds checking for both ends
bool process_data_safe(int *data, size_t data_size, int index, int value) {
    // Check for negative index AND upper bound
    if (index < 0 || (size_t)index >= data_size) {
        return false;  // Reject invalid index
    }
    data[index] = value;
    return true;
}

// SAFE: Proper loop bounds
void copy_reversed_safe(char *dest, size_t dest_size,
                        const char *src, size_t src_len) {
    if (src_len == 0 || src_len > dest_size) {
        return;
    }

    const char *end = src + src_len - 1;

    // Loop only while within valid source range
    for (size_t i = 0; i < src_len; i++) {
        dest[i] = *end--;
    }
}

// SAFE: Validate offset before arithmetic
bool write_at_offset_safe(char *buffer, size_t buffer_size,
                          size_t user_offset, char value) {
    // Ensure offset is large enough and result fits in buffer
    if (user_offset < 100) {
        return false;  // Would underflow
    }

    size_t index = user_offset - 100;
    if (index >= buffer_size) {
        return false;  // Would overflow
    }

    buffer[index] = value;
    return true;
}

Exploited in the Wild

Fortinet Buffer Underflow (Fortinet, 2025)

CVE-2025 series vulnerabilities in Fortinet products included buffer underflow conditions that could be exploited for code execution on network security appliances.

Zoom Client Buffer Underflow (Zoom, 2025)

Buffer underflow vulnerabilities in Zoom apps and SDKs (March 2025) could allow attackers to compromise meeting participants through crafted data.

Dell NetWorker Buffer Underflow (Dell, 2025)

Critical buffer underflow vulnerability in Dell NetWorker Management Console third-party components with public exploit available.


Tools to test/exploit

  • AddressSanitizer — detects buffer underwrites at runtime with precise location reporting.

  • Valgrind — memory error detector that identifies invalid memory access before buffer start.

  • AFL++ — fuzzer effective at discovering boundary condition bugs including underwrites.


CVE Examples

  • CVE-2023-27997 — Fortinet FortiOS buffer underflow enabling RCE.

  • CVE-2022-42475 — Fortinet FortiOS SSL-VPN heap buffer underflow exploited in the wild.

  • CVE-2021-32760 — containerd buffer underflow vulnerability.


References

  1. MITRE. "CWE-124: Buffer Underwrite ('Buffer Underflow')." https://cwe.mitre.org/data/definitions/124.html

  2. CERT. "ARR30-C. Do not form or use out-of-bounds pointers or array subscripts." https://wiki.sei.cmu.edu/confluence/display/c/ARR30-C