3

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

我昨天大部分时间都在追踪崩溃和奇怪的行为,最终结果证明是由以下行引起的:

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

该索引显然导致超出数组范围的写入。这会导致指针变量的破坏,从而导致该指针稍后出现意外行为。

可以帮助缓解此类问题的三件事是:

  1. 代码审查

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

  2. valgrind

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

  3. -fstack-protector-all

    在过去,我曾经-fstack-protector-all检测过像上面这样的溢出,但出于某种奇怪的原因,它在这种情况下没有标记任何东西。

那么任何人都可以就我如何识别这种超支提供任何想法吗?通过改进上述列表或全新的东西。

编辑:到目前为止,一些答案提到了相当昂贵的商业产品。在这个阶段,我认为我无法说服购买这种工具的权力,所以我想将工具限制为便宜/免费。是的,你得到你所支付的,但有一些改进总比没有好。

4

3 回答 3

3

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

例如,使用此代码:

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 行]

于 2012-01-27T16:44:09.400 回答
1

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

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

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

显然,Valgrind 进行动态分析而不是静态分析,这本身就是另一个讨论。

于 2012-01-27T18:22:20.967 回答
0

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

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

它目前可用于 C,但尚未用于 C++。

于 2012-01-27T18:47:30.293 回答