경고 C6029
'function' 호출에서 가능한 버퍼 오버런
un검사ed buffer length/size 매개 변수로 인해 호출된 함수에서 버퍼 오버런이 발생할 수 있습니다.
설명
이 경고는 코드가 버퍼 및 크기를 사용하는 함수에 검사 없는 크기를 전달한다는 것을 나타냅니다. 코드는 일부 외부 원본에서 읽은 데이터가 버퍼 크기보다 작은지 확인하지 않습니다. 공격자는 의도적으로 크기가 예상보다 큰 값을 지정하여 버퍼 오버런이 발생할 수 있습니다. 일반적으로 신뢰할 수 없는 외부 소스에서 데이터를 읽을 때마다 해당 데이터의 유효성을 확인해야 합니다. 크기를 확인하여 예상 범위에 있는지 확인하는 것이 적절합니다.
코드 분석 이름: USING_TAINTED_DATA
예시
다음 코드는 주석이 추가된 함수 std::fread
를 두 번 호출할 때 이 경고를 생성합니다. 코드는 첫 번째 호출을 사용하여 이후 호출에서 읽을 데이터의 길이를 결정합니다. 첫 번째 호출 후 분석은 신뢰할 수 없는 원본에서 오는 것으로 표시 dataSize
합니다. 따라서 코드가 신뢰할 수 없는 값을 두 번째 std::fread
호출에 전달하면 분석기에서 이 경고를 생성합니다. 악의적인 행위자가 파일을 수정하고 호출이 배열을 오버플로 buffer
하도록 std::fread
할 수 있습니다. 실제 코드에서는 반환 값 std::fread
에 따라 오류 복구도 처리해야 합니다. 간단히 하기 위해 이러한 예제에서는 의도적으로 오류 복구 코드 제외합니다.
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);
}
이 문제에 대한 수정 사항은 데이터의 특성과 진단을 트리거하는 주석이 추가된 함수의 동작에 따라 달라집니다. 자세한 내용은 해당 함수에 대한 설명서를 참조하세요. 간단한 해결 방법은 두 번째 호출 전에 크기를 검사 것입니다std:fread
. 다음 예제에서는 함수를 종료하는 예외를 throw합니다. 대신 대부분의 실제 코드에는 시나리오와 관련된 오류 복구 전략이 있습니다.
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);
}
함수와 유사한 함수에서 std:fread
코드는 많은 양의 데이터를 읽어야 할 수 있습니다. 큰 데이터를 처리하려면 크기가 알려지면 버퍼의 크기를 동적으로 할당할 수 있습니다. 또는 나머지 데이터에서 읽기 위해 필요에 따라 여러 번 호출 std:fread
할 수 있습니다. 버퍼를 동적으로 할당하는 경우 큰 값에 대한 메모리 부족 악용이 발생하지 않도록 크기에 제한을 두는 것이 좋습니다. 이 방법은 이미 크기 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`...
}
}
참고 항목
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기