我最近在一个正在使用HP fortify的项目上运行了代码扫描。据报道,我对ReadFile存在严重问题。我从不传递空缓冲区。有关如何解决潜在缓冲区溢出问题的任何建议。
摘要
serialport.cpp中的函数Read()可能能够在第225行的已分配内存的边界外写入,这可能会破坏数据,导致程序崩溃或导致恶意代码的执行。
DWORD serialport::Read(std::vector<char> & buffer)
{
DWORD read = 0;
int val = ReadFile(h, &buffer[0], buffer.size(), &read, NULL);
if (val == 0)
{
LPCSTR ptr = "";
PrintError(ptr);
}
buffer.resize(read);
return read;
}
我从不传递空缓冲区
但是有一天可能会有其他人。你错误地在函数内部对代码进行评估,并且知道你在函数之外做了什么。该函数可以传递一个空的std::vector<char> &
。总有一天,它会。处理那个案子。
您永远不会传递空缓冲区,但代码扫描工具不知道这一点。我曾与之合作过的只关注单个函数,所以假设实际参数可以是任何函数。
如果缓冲区为空,则&buffer[0]
是未定义的行为。您已尝试创建指向不存在的内存的指针。这可能是代码扫描工具的反应。
尽管&buffer[0]
是一个无效的指针,但你可能会发现什么都不会出错,因为没有任何东西可以访问它。但是buffer[0]
本身是一个无效的访问,即使你没有阅读或写入该元素。
虽然你可能会选择使用buffer.data()
,但我仍然会对此保持警惕。它似乎只为非空数组定义。
要解决这个问题,......
选项1:将assert(!buffer.empty());
添加到函数的开头。
选项2:更仔细地获取指针,
DWORD read = 0;
char trash;
void *pBuffer = buffer.empty() ? &trash : buffer.data();
int val = ReadFile(h, pBuffer, buffer.size(), &read, NULL);
虽然该工具没有抱怨,但我还要确保buffer.size()
(一个std::size_t
)适合DWORD,这在64位版本中可能不是这样。