简体   繁体   English

从文件中读取索引是否存在缓冲区溢出漏洞?

[英]Is reading an index from a file a buffer overflow vulnerability?

I recently used a static analysis tool (Checkmarx) to scan the source code of an old game engine to see if there are any buffer overflow vulnerabilities in it. 我最近使用静态分析工具(Checkmarx)来扫描旧游戏引擎的源代码,以查看其中是否存在任何缓冲区溢出漏洞。 I was surprised to see that the following code was flagged as a possible source of buffer overflows: 我很惊讶地看到以下代码被标记为缓冲区溢出的可能来源:

// Get a pointer to a file that describes a 3D model
std::string filename = "my_3D_model.obj"
FILE* stream;
fopen_s(&stream, filename.c_str(), "rb");

// Read the number of vertices that make up the 3D model
int numVertices = 0;
fread(&numVertices, sizeof(int), 1, stream);

// Read the vertices and store them in a vector
// The static analysis tool doesn't complain about the use of numVertices to
// reserve space and to read from the file
std::vector<Vertex> vertices;
vertices.reserve(numVertices);
fread(vertices.data(), sizeof(Vertex), numVertices, stream);

// ...

// Copy the vertices from the vector to an array that has been allocated on the heap
// The static analysis tool complains because numVertices, which was read from a file,
// is being used as an index
Vertex* meshVertices = new Vertex[numVertices];
for (int i = 0; i < numVertices; i++)
{
    meshVertices[i] = vertices[i];
}

The static analysis tool calls this an "Index from input buffer overflow vulnerability". 静态分析工具将其称为“来自输入缓冲区溢出漏洞的索引”。 It sees that int i is ranging from 0 to numVertices , which was read from a file, and it thinks that that might cause a buffer overflow. 它看到int i的范围从0到numVertices ,它是从文件中读取的,它认为这可能导致缓冲区溢出。 But is it really possible in this particular case? 但在这种特殊情况下它真的可能吗? numVertices is being used to allocate the size of the buffers, so I don't see how a buffer overflow could occur. numVertices用于分配缓冲区的大小,因此我没有看到缓冲区溢出是如何发生的。 And if it is possible, how would you prevent it? 如果有可能,你会如何防止它? Note that I can't change the types of the buffers because that would break too much code. 请注意,我无法更改缓冲区的类型,因为这会破坏太多代码。

Thanks for any information! 感谢您的任何信息!

The warning is absolutely correct. 警告绝对正确。 You're reading a signed int from an external source and then promoting it to a size_t when you call reserve and fread . 您正在从外部源读取已签名的int ,然后在调用reservefread时将其提升为size_t Since size_t is an unsigned type, if the value you read from the file is a negative number the resulting value when promoted to size_t is going to be much larger than the absolute value of numVertices on most platforms. 由于size_t是无符号类型,如果从文件中读取的值是负数,则提升为size_t时的结果值将远大于大多数平台上numVertices的绝对值。 The result is you're going to try to reserve and read a huge number of vectors. 结果是你将尝试保留并读取大量的向量。 If those two operations succeed, you're then going to try to new a negative array size. 如果这两个操作成功,那么您将尝试new的负数组大小。 Your for loop is guaranteed never to execute if you get that far. 保证你的for循环永远不会执行,如果你走得那么远。

The fix is to read the value as an unsigned int, or better yet a size_t , although that will require you to alter the code that writes the value. 修复是将值读取为unsigned int,或者更好的是size_t ,尽管这将要求您更改写入值的代码。 Another option is to at least validate the value. 另一种选择是至少验证价值。 Trusting data from external sources is a great way to become this week's exploit. 信任来自外部资源的数据是成为本周漏洞的好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM