CWE-124

Buffer Underwrite (‘Buffer Underflow’). [Memory-Buffer-Errors, Improper-Control-Of-A-Resource-Through-Its-Lifetime]

Required inputs: IR, StaticSemanticAnalysis

The product writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer. This typically occurs when a pointer or its index is decremented to a position before the buffer, when pointer arithmetic results in a position before the beginning of the valid memory location, or when a negative index is used.
Demonstrative Examples
Example 1

In the following C/C++ example, a utility function is used to trim trailing whitespace from a character string. The function copies the input string to a local character string and uses a while statement to remove the trailing whitespace by moving backward through the string and overwriting whitespace with a NUL character.

Example Language:C
    char* trimTrailingWhitespace(char *strMessage, int length) {
        char *retMessage;
        char *message = malloc(sizeof(char)*(length+1));

        // copy input string to a temporary string
        char message[length+1];
        int index;
        for (index = 0; index < length; index++) {
            message[index] = strMessage[index];
        }
        message[index] = '\0';

        // trim trailing whitespace
        int len = index-1;
        while (isspace(message[len])) {
            message[len] = '\0';
            len--;
        }

        // return string without trailing whitespace
        retMessage = message;
        return retMessage;
    }

However, this function can cause a buffer underwrite if the input character string contains all whitespace. On some systems the while statement will move backwards past the beginning of a character string and will call the isspace() function on an address outside of the bounds of the local buffer.

Example 2

The following is an example of code that may result in a buffer underwrite. This code is attempting to replace the substring "Replace Me" in destBuf with the string stored in srcBuf. It does so by using the function strstr(), which returns a pointer to the found substring in destBuf. Using pointer arithmetic, the starting index of the substring is found.

Example Language:C
    int main() {
        ...
        char *result = strstr(destBuf, "Replace Me");
        int idx = result - destBuf;
        strcpy(&destBuf[idx], srcBuf);
        ...
    }

In the case where the substring is not found in destBuf, strstr() will return NULL, causing the pointer arithmetic to be undefined, potentially setting the value of idx to a negative number. If idx is negative, this will result in a buffer underwrite of destBuf.

Excerpts from CWE [https://cwe.mitre.org], Copyright (C) 2006-2026, the MITRE Corporation. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

arithmetic_out_of_bounds

Pointer arithmetic on {node0} might create pointer below lower boundary of {name0}

None

False

out_of_bounds

Access into array is below lower boundary

None

False

possible_indirect_out_of_bounds

Pointer-indirect access through {node0} might be below lower boundary accessing {name0}

None

False

possible_out_of_bounds

Access into array might be below lower boundary.

None

False

undereferenced_arithmetic_out_of_bounds

Pointer arithmetic on {node0} might create pointer one past the end of {name0} (but not dereferenced)

None

False

undereferenced_out_of_bounds

Access is one past the end of the array (but not dereferenced)

None

False

undereferenced_possible_indirect_out_of_bounds

Pointer-indirect access through {node0} might be one past the end accessing {name0} (but not dereferenced)

None

False

undereferenced_possible_out_of_bounds

Access might be one past the end of the array (but not dereferenced)

None

False

Options

abstract_interpretation_out_of_bounds

abstract_interpretation_out_of_bounds : bool = True

Use additional "symbolic expression analysis" as postprocessing step. This can remove false positives, but might require more time. Option is automatically active if option StaticSemanticAnalysis/performance.general.enhanced_analysis is active.
 

exclude_very_high_indices

exclude_very_high_indices : bool = True

Enables heuristic to detect false positives: When index used for array access is very high in comparison to the array's size, assume false positive.
 

report_unbounded_arrays

report_unbounded_arrays : bool = True

If true, accesses into arrays with unknown bound are reported as being potentially outside the allowed range. This affects arrays like extern char buf[];.
 

report_undereferenced_one_past_the_end

report_undereferenced_one_past_the_end : bool = False

If true, report accesses one past the end of an array even if there is no dereference of the resulting pointer.
 

report_unknown_index

report_unknown_index : bool = False

If false, do not report possible out-of-bound findings for which the analysis was not able to infer any restricting information about the array index (this can lead to excluding both false positives and true findings).