Buffer Access with Incorrect Length Value

Description

Buffer Access with Incorrect Length Value occurs when software performs sequential buffer operations using a length value that does not correctly represent the buffer being operated on, causing memory access outside buffer boundaries. This typically happens when copy operations use a length value based on the wrong buffer (source instead of destination), when the length parameter doesn't account for null terminators, or when length calculations are incorrect. When the computed length exceeds the actual size of the destination buffer, a buffer overflow occurs, potentially allowing attackers to overwrite adjacent memory, corrupt data structures, or execute arbitrary code.

Risk

This vulnerability can lead to crashes, arbitrary code execution, and complete system compromise. Buffer overflows remain one of the most dangerous and exploited vulnerability classes. When the length value exceeds the destination buffer, data overwrites adjacent memory, potentially including return addresses, function pointers, or security-critical data. Attackers who control the overflow can redirect program execution to malicious code. Even without code execution, memory corruption can cause denial of service through crashes or lead to information disclosure. The vulnerability is especially common in C and C++ where manual memory management is required.

Solution

Always use the destination buffer's size for length calculations in copy operations. Double-check that buffer sizes and length parameters match before operations. Use memory-safe languages like Java, Python, or Rust when possible. In C/C++, use safe string libraries like SafeStr, Microsoft's Strsafe.h, or strlcpy/strlcat. Enable compiler protections including stack canaries (/GS flag in MSVC, FORTIFY_SOURCE in GCC). Deploy ASLR, PIE, and DEP/NX as defense-in-depth measures. Run with minimum necessary privileges to limit damage from successful exploits. Use static analysis tools to detect buffer handling errors during development.

Common Consequences

ImpactDetails
AvailabilityScope: Availability

Denial of Service - Buffer overflows commonly cause crashes, infinite loops, or resource exhaustion.
Integrity, Confidentiality, AvailabilityScope: Integrity, Confidentiality, Availability

Execute Unauthorized Code - Attackers can leverage overflows to execute arbitrary code, compromising system integrity and confidentiality.
Access ControlScope: Access Control

Bypass Protection Mechanism - Successful code execution can subvert other security controls.

Example Code

Vulnerable Code

// Vulnerable: No size limit on copy
void vulnerable_copy_hostname(struct hostent *hp) {
    char hostname[64];

    // Vulnerable: strcpy doesn't check destination size
    // If hp->h_name > 63 characters, buffer overflow occurs
    strcpy(hostname, hp->h_name);

    printf("Hostname: %s\n", hostname);
}
// Vulnerable: Uses source buffer size for destination
void vulnerable_copy(void) {
    char source[100] = "A string that might be longer than destination";
    char dest[20];

    // Vulnerable: sizeof(source) is 100, but dest is only 20
    strncpy(dest, source, sizeof(source) - 1);
    // Writes up to 99 bytes into 20-byte buffer!
}
// Vulnerable: Uses length parameter instead of buffer size
int vulnerable_copy_path(char *filename, int length) {
    char buf[MAX_PATH];  // MAX_PATH is 256

    // Vulnerable: 'length' might be larger than MAX_PATH
    strncpy(buf, filename, length);

    // If length > MAX_PATH, buffer overflow
    process_path(buf);
    return 0;
}
// Vulnerable: Incorrect length calculation
void vulnerable_concat(char *user_input) {
    char buffer[100];
    char prefix[] = "Hello, ";

    strcpy(buffer, prefix);

    // Vulnerable: Doesn't account for prefix already in buffer
    strncat(buffer, user_input, sizeof(buffer));
    // Should be: sizeof(buffer) - strlen(buffer) - 1
}
// Vulnerable: Using wrong size in memcpy
void vulnerable_memcpy(const char* input, size_t input_len) {
    char destination[64];

    // Vulnerable: Copies input_len bytes regardless of destination size
    memcpy(destination, input, input_len);

    // If input_len > 64, overflow occurs
}
// Vulnerable: Off-by-one in size calculation
void vulnerable_read(int fd) {
    char buffer[256];

    // Vulnerable: Reads 256 bytes but doesn't leave room for null
    read(fd, buffer, sizeof(buffer));
    buffer[256] = '\0';  // Off-by-one: writes past buffer!
}

Fixed Code

// Fixed: Use destination size
void fixed_copy_hostname(struct hostent *hp) {
    char hostname[64];

    // Fixed: Use destination size and ensure null termination
    strncpy(hostname, hp->h_name, sizeof(hostname) - 1);
    hostname[sizeof(hostname) - 1] = '\0';

    printf("Hostname: %s\n", hostname);
}
// Fixed: Use destination buffer size
void fixed_copy(void) {
    char source[100] = "A string that might be longer than destination";
    char dest[20];

    // Fixed: Use sizeof(dest), not sizeof(source)
    strncpy(dest, source, sizeof(dest) - 1);
    dest[sizeof(dest) - 1] = '\0';
}
// Fixed: Validate length against buffer size
int fixed_copy_path(char *filename, int length) {
    char buf[MAX_PATH];

    // Fixed: Use minimum of length and buffer size
    size_t copy_len = (length < sizeof(buf)) ? length : sizeof(buf) - 1;
    strncpy(buf, filename, copy_len);
    buf[copy_len] = '\0';

    process_path(buf);
    return 0;
}
// Fixed: Correct length calculation for concatenation
void fixed_concat(char *user_input) {
    char buffer[100];
    char prefix[] = "Hello, ";

    strcpy(buffer, prefix);

    // Fixed: Calculate remaining space
    size_t remaining = sizeof(buffer) - strlen(buffer) - 1;
    strncat(buffer, user_input, remaining);
}

// Better: Use snprintf
void fixed_concat_snprintf(char *user_input) {
    char buffer[100];

    // snprintf handles size limits automatically
    snprintf(buffer, sizeof(buffer), "Hello, %s", user_input);
}
// Fixed: Validate input length before copy
void fixed_memcpy(const char* input, size_t input_len) {
    char destination[64];

    // Fixed: Only copy up to destination size
    size_t copy_len = (input_len < sizeof(destination)) ?
                      input_len : sizeof(destination);
    memcpy(destination, input, copy_len);

    // Ensure null termination if treating as string
    if (copy_len < sizeof(destination)) {
        destination[copy_len] = '\0';
    } else {
        destination[sizeof(destination) - 1] = '\0';
    }
}
// Fixed: Correct size calculation for read
void fixed_read(int fd) {
    char buffer[256];

    // Fixed: Leave room for null terminator
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
    if (bytes_read >= 0) {
        buffer[bytes_read] = '\0';  // Safe: bytes_read < 256
    }
}
// Best practice: Use safe string functions
#include <string.h>
#ifdef _MSC_VER
#include <strsafe.h>
#endif

void best_practice_copy(const char* source) {
#ifdef _MSC_VER
    char dest[64];
    // Microsoft's safe string function
    StringCchCopy(dest, sizeof(dest), source);
#elif defined(__STDC_LIB_EXT1__)
    char dest[64];
    // C11 bounds-checking interface
    strcpy_s(dest, sizeof(dest), source);
#else
    char dest[64];
    // BSD-style safe copy
    strlcpy(dest, source, sizeof(dest));
#endif
}

  • CWE-119: Improper Restriction of Operations within Bounds of Memory Buffer (parent)
  • CWE-806: Buffer Access Using Size of Source Buffer (child - specific variant)
  • CWE-130: Improper Handling of Length Parameter Inconsistency (can precede)
  • CWE-120: Buffer Copy without Checking Size of Input (related)
  • CWE-787: Out-of-bounds Write (related)

References

  1. MITRE Corporation. "CWE-805: Buffer Access with Incorrect Length Value." https://cwe.mitre.org/data/definitions/805.html
  2. Microsoft. "Strsafe.h Functions." https://docs.microsoft.com/en-us/windows/win32/menurc/strsafe-ovw
  3. CERT C Coding Standard. "STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator."