c-识别/防止静态缓冲区溢出的工具和方法



是否有任何工具或方法可以在静态定义的数组(即char[1234]而不是malloc(1234))中识别缓冲区溢出?

昨天的大部分时间我都在追踪撞车事故和奇怪的行为,这些行为最终被证明是由以下线路引起的:

// ensure string is nul terminated due to stupid snprintf
error_msg[error_msg_len] = '';

这个索引显然导致写入超出了数组的范围。这会导致指针变量的崩溃,导致该指针稍后出现意外行为。

脑海中浮现的三件有助于缓解这些问题的事情是:

  1. 代码审查

    这还没有完成,但我正在努力。

  2. valgrind

    我经常在开发过程中使用valgrind来检测内存问题,但它不处理静态数组。在上面的例子中,它只向我显示了一些症状,例如被重击的指针的free()无效。

  3. -fstack-protector-all

    在过去,我曾使用-fstack-protector-all来检测如上所述的溢出,但出于某种奇怪的原因,它在本例中没有标记任何内容。

那么,有人能为我如何识别这种超支提供任何想法吗?要么在上面的列表上进行改进,要么做一些全新的事情。

编辑:到目前为止,一些答案提到了相当昂贵的商业产品。在这个阶段,我不认为我能说服当权者购买这样的工具,所以我想把工具限制在便宜/免费的范围内。是的,你付出了什么就得到了什么,但有些改进总比没有好。

静态分析器工具能够检测一些缓冲区溢出。

例如,使用此代码:

char bla[1024];
int i;
for (i = 0; i <= 1024; i++)
    bla[i] = 0;

以下是PC Lint/flexelint的报告:

tst.c 9警告661:操作员"["可能访问越界指针(1超出数据末尾)[参考:文件tst.c:行8,9]

您是否尝试过实验性的Valgrind工具"SGCheck:一个实验性堆栈和全局数组溢出检测器",而不是默认的"memcheck"工具?

http://valgrind.org/docs/manual/sg-manual.html

我自己还没有尝试过,但它似乎涵盖了你感兴趣的一些类型的错误。

显然,Valgrind做的是动态分析,而不是静态分析,这本身就是一个完全不同的讨论。

我们的CheckPointer工具是一个动态分析工具,无论数组在哪里,它都会捕获数组上的越界错误。

CheckPointer捕获了许多Valgrind无法捕获的东西,例如,无论在哪里分配,都引用任何结构或结构字段之外的内容,包括OP所示问题中的静态数组。Valgrind不能检测到这种溢出,因为它不知道被操作的数据的实际形状;这需要理解编程语言,例如C.Valgrind只能检测分配内存之外的引用。Checkpoint之所以能够做到这一点,是因为它非常了解C;它使用完全编译器风格的C前端来收集类型和关键大小信息。

它目前可用于C,但还不能用于C++。

最新更新