Freigeben über


Warnung C6029

Möglicher Pufferüberlauf beim Aufruf von "function"

Möglicher Pufferüberlauf in der aufgerufenen Funktion aufgrund eines deaktivierten Pufferlängen-/Größenparameters.

Hinweise

Diese Warnung gibt an, dass Code eine nicht aktivierte Größe an eine Funktion übergibt, die einen Puffer und eine Größe akzeptiert. Der Code überprüft nicht, ob die aus einer externen Quelle gelesenen Daten kleiner als die Puffergröße sind. Ein Angreifer kann absichtlich einen größeren als erwarteten Wert für die Größe angeben, was zu einem Pufferüberlauf führen kann. Überprüfen Sie grundsätzlich beim Lesen von Daten aus einer nicht als vertrauenswürdig eingestuften externen Quelle die Gültigkeit der Daten. Es ist angemessen, die Größe zu überprüfen, um sicherzustellen, dass sie sich im erwarteten Bereich befindet.

Codeanalysename: USING_TAINTED_DATA

Beispiel

Der folgende Code generiert diese Warnung, wenn sie die kommentierte Funktion std::fread zweimal aufruft. Der Code verwendet den ersten Aufruf, um die Länge der Daten zu bestimmen, die in späteren Aufrufen gelesen werden sollen. Nach dem ersten Aufruf markieren Analysezeichen dataSize als aus einer nicht vertrauenswürdigen Quelle. Wenn der Code den nicht vertrauenswürdigen Wert an den zweiten std::fread Aufruf übergibt, generiert die Analyse diese Warnung. Ein böswilliger Akteur könnte die Datei ändern und dazu führen, dass der Aufruf std::fread des buffer Arrays überläuft. Im realen Code sollten Sie auch die Fehlerwiederherstellung basierend auf dem Rückgabewert von std::fread. Aus Gründen der Einfachheit lassen diese Beispiele absichtlich Fehler Wiederherstellungscode aus.

void processData(FILE* file)
{
    const size_t MAX_BUFFER_SIZE = 100;
    uint32_t buffer[MAX_BUFFER_SIZE]{};
    uint8_t dataSize = 0;

    // Read length data from the beginning of the file
    fread(&dataSize, sizeof(uint8_t), 1, file);
    // Read the rest of the data based on the dataSize
    fread(buffer, sizeof(uint32_t), dataSize, file);
}

Die Lösung für das Problem hängt von der Art der Daten und dem Verhalten der kommentierten Funktion ab, die die Diagnose auslöst. Weitere Informationen finden Sie in der Dokumentation zu dieser Funktion. Eine einfache Lösung besteht darin, die Größe vor dem zweiten Aufruf zu std:freadüberprüfen. Im nächsten Beispiel wird eine Ausnahme ausgelöst, um die Funktion zu beenden. Der meiste reale Code hätte stattdessen eine Für das Szenario spezifische Fehlerwiederherstellungsstrategie.

void processData(FILE* file)
{
    const size_t MAX_BUFFER_SIZE = 100;
    uint32_t buffer[MAX_BUFFER_SIZE]{};
    uint8_t dataSize = 0;

    fread(&dataSize, sizeof(uint32_t), 1, file);

    if (dataSize > MAX_BUFFER_SIZE)
    {
        throw std::runtime_error("file data unexpected size");
    }

    fread(buffer, sizeof(uint32_t), dataSize, file);
}

In std:fread und ähnlichen Funktionen muss der Code möglicherweise große Datenmengen lesen. Um große Daten zu verarbeiten, können Sie die Größe des Puffers dynamisch zuordnen, nachdem die Größe bekannt wurde. Alternativ können Sie bei Bedarf mehrere Male aufrufen std:fread , um die restlichen Daten zu lesen. Wenn Sie den Puffer dynamisch zuordnen, empfiehlt es sich, einen Grenzwert für die Größe zu setzen, um zu vermeiden, dass ein Nichtspeicher-Exploit für große Werte eingeführt wird. Wir verwenden diesen Ansatz in unserem Beispiel nicht, da er bereits durch die Größe von uint8_t.

void processDataDynamic(FILE* file)
{
    uint8_t dataSize = 0;
    fread(&dataSize, sizeof(uint8_t), 1, file);
    
    // Vector with `dataSize` default initialized objects
    std::vector<uint32_t> vecBuffer(dataSize);

    fread(&vecBuffer[0], sizeof(uint32_t), dataSize, file);
}
void processDataMultiple(FILE* file)
{
    const size_t MAX_BUFFER_SIZE = 100;
    uint32_t buffer[MAX_BUFFER_SIZE]{};
    uint8_t dataSize = 0;

    fread(&dataSize, sizeof(uint32_t), 1, file);

    while( dataSize > 0 )
    {
        size_t readSize = dataSize > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : dataSize;
        readSize = fread(buffer, sizeof(uint32_t), readSize, file);
        dataSize = dataSize - readSize;
        // Process the data in `buffer`...
    }
}

Siehe auch

Regelsätze für C++-Code
Verwenden von SAL-Anmerkungen zur Reduzierung von Codefehlern