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

时间:2012-01-27 16:39:05

标签: c buffer-overflow gcc4

是否有任何工具或方法可以识别静态定义的数组中的缓冲区溢出(即。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 个答案:

答案 0 :(得分:3)

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

例如使用此代码:

char bla[1024];
int i;

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

以下是PC-Lint / flexelint的报告:

  

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

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

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