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