Falsche Berechnung der Puffergröße

Beschreibung

Falsche Berechnung der Puffergröße tritt auf, wenn ein Programm einen Puffer allokiert, aber dessen erforderliche Größe falsch berechnet, was zu einem Puffer führt, der zu klein für die zu haltenden Daten ist. Häufige Ursachen umfassen Off-by-One-Fehler (Vergessen von NULL-Terminatoren), Integer-Overflow in Größenberechnungen, Signed/Unsigned-Verwechslung, falsche Annahmen über Datencodierungsgrößen (UTF-8 vs UTF-16) und das Versäumnis, Datenexpansion während der Verarbeitung zu berücksichtigen. Wenn nachfolgende Operationen die ursprünglich beabsichtigte (größere) Größe verwenden, treten Buffer Overflows auf.

Risiko

Falsche Puffergrößenberechnungen sind hochgradig ausnutzbar und haben zahlreiche Remote-Code-Execution-Schwachstellen ermöglicht. Integer-Overflow in Größenberechnungen ist besonders gefährlich: Die Multiplikation größer benutzergesteuerter Werte kann zu kleinen Werten umwickeln, was winzige Allokationen zur Folge hat, die massiv übergelaufen werden. Diese Schwachstellenklasse betrifft alle Software, die dynamische Speicherallokation durchführt, besonders Netzwerkdienste, die variabel lange Daten parsen, Bildprozessoren, die Dimensionen verarbeiten, und Kompressionsbibliotheken. Ausnutzung führt typischerweise zu Heap-Beschädigung und beliebiger Code-Ausführung.

Lösung

Verifizieren Sie immer arithmetische Operationen, die in Größenberechnungen verwendet werden, auf potentiellen Overflow. Prüfen Sie, dass Multiplikationsergebnisse SIZE_MAX nicht überschreiten, bevor allokiert wird. Berücksichtigen Sie NULL-Terminatoren, Padding und Alignment-Anforderungen. Verwenden Sie sichere Allokationsmuster, die Größen validieren. Erwägen Sie die Verwendung von calloc() für Multiplikation, da es Overflow erkennen kann. Verwenden Sie Compiler-Flags wie -ftrapv, um Signed-Overflow zu erkennen. Wenden Sie statische Analyse an, um Berechnungsfehler zu identifizieren. Bevorzugen Sie Hochsprachen oder sichere Abstraktionen, die Allokation automatisch handhaben.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Speicherbeschädigung

Unterdimensionierte Puffer werden während Datenoperationen übergelaufen, was Heap-Metadaten und angrenzende Allokationen beschädigt.
ZugriffskontrolleBereich: Code-Ausführung

Heap-Beschädigung durch unterdimensionierte Puffer ermöglicht beliebige Code-Ausführung durch Heap-Exploitation-Techniken.
VerfügbarkeitBereich: Denial-of-Service

Speicherbeschädigung verursacht häufig Abstürze; Integer-Overflow bei Allokation kann Ressourcenerschöpfung verursachen.

Beispielcode + Lösungscode

Anfälliger Code

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

// ANFÄLLIG: Off-by-One - vergisst NULL-Terminator
char *copy_string_wrong(const char *src) {
    size_t len = strlen(src);
    char *dst = malloc(len);  // Sollte len + 1 sein

    strcpy(dst, src);  // Schreibt NULL-Byte über Allokation hinaus
    return dst;
}

// ANFÄLLIG: Integer-Overflow bei Multiplikation
void *allocate_matrix(unsigned int rows, unsigned int cols) {
    // Wenn rows * cols überläuft, allokiert winzigen Puffer
    size_t size = rows * cols * sizeof(int);

    int *matrix = malloc(size);

    // Schleife verwendet ursprüngliche row/col-Werte - massiver Overflow
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            matrix[i * cols + j] = 0;
        }
    }
    return matrix;
}

// ANFÄLLIG: Signed/Unsigned-Verwechslung
void *allocate_items(int num_items) {
    // Wenn num_items negativ ist, produziert Berechnung falsches Ergebnis
    // Bei Cast zu size_t wird riesiger Wert
    size_t size = num_items * sizeof(Item);

    return malloc(size);  // Kann fehlschlagen oder enormen Puffer allokieren
}

Korrigierter Code

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

// SICHER: NULL-Terminator berücksichtigen
char *copy_string_safe(const char *src) {
    size_t len = strlen(src);

    // Auf Overflow beim Addieren von 1 prüfen
    if (len == SIZE_MAX) {
        return NULL;
    }

    char *dst = malloc(len + 1);  // NULL-Terminator einschließen
    if (dst) {
        memcpy(dst, src, len);
        dst[len] = '\0';
    }
    return dst;
}

// SICHER: Auf Multiplikations-Overflow prüfen
void *allocate_matrix_safe(size_t rows, size_t cols) {
    // Auf Overflow bei rows * cols prüfen
    if (rows != 0 && cols > SIZE_MAX / rows) {
        return NULL;  // Würde überläufen
    }

    size_t num_elements = rows * cols;

    // Auf Overflow bei num_elements * sizeof(int) prüfen
    if (num_elements > SIZE_MAX / sizeof(int)) {
        return NULL;  // Würde überläufen
    }

    size_t size = num_elements * sizeof(int);

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

// SICHER: calloc für overflow-geprüfte Allokation verwenden
void *allocate_items_safe(size_t num_items) {
    // Unvernünftige Größen ablehnen
    if (num_items > MAX_ITEMS) {
        return NULL;
    }

    // calloc kann Overflow bei Multiplikation erkennen
    return calloc(num_items, sizeof(Item));
}

// SICHER: Umfassende Größenprüfungsfunktion
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;
}

Ausgenutzt in der Praxis

Qualcomm-Chipsatz-Schwachstellen (Mobile Geräte, 2025)

Mehrere hochschwere Puffergrößenberechnungsschwachstellen in Qualcomm-Chipsätzen, die Android-Geräte betreffen, ermöglichen potentielle Code-Ausführung auf Millionen von Mobilgeräten.

Schneider Electric Modicon PLCs (Industriesteuerung, 2025)

CVE, das Schneider Electric Modicon M580 PLCs mit falscher Puffergrößenberechnung betrifft, ermöglicht Denial-of-Service-Angriffe auf kritische industrielle Infrastruktur.

Google Android Medienverarbeitung (Android, mehrfach)

Mehrere Puffergrößenberechnungsschwachstellen in Android-Medienverarbeitungskomponenten haben Remote Code Execution durch bösartige Mediendateien ermöglicht.


Tools zum Testen/Ausnutzen

  • AddressSanitizer — erkennt Buffer Overflows durch unterdimensionierte Allokationen.

  • Coverity — statische Analyse, die Puffergrößenberechnungsfehler identifiziert.

  • AFL++ — Fuzzer, der effektiv beim Auslösen von Größenberechnungsfehlern ist.


CVE-Beispiele

  • CVE-2021-21300 — Git Puffergrößenberechnung ermöglicht RCE.

  • CVE-2022-0778 — OpenSSL Größenberechnung verursacht DoS.

  • CVE-2023-4863 — libwebp Heap-Buffer-Overflow durch Größenberechnungsfehler.


Referenzen

  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