我创建了一个错误的程序 - buggy.c - 这是缓冲区t的缓冲区溢出方案。 您可以看到我正在编写超过5个索引。它工作正常。它永远不会给我一个错误。我在想,为什么会那样?我甚至试过Valgrind,这也找不到这个问题。你能告诉我这里有什么问题吗?
void buffer_overflow(void)
{
int t[5];
int i = 0;
for(i = 0; i<=7; i++)
{
t[i] = i;
}
/** this will cause buffer overflow **/
printf("Memory_overflow_completed\r\n");
}
int main(int argc, char **argv)
{
buffer_overflow();
return 0;
}
$gcc -g buggy.c -o buggy.out -lefence
$./buggy.out
但是,我没有遇到任何崩溃。这里没有电栅栏的效果。 我错过了什么? 我在这里发布了类似的问题gcc with electric fence library does not take effect,但似乎还没有答案。 我在FC19上运行这个例子。有人有答案吗?即使是valgrind也未能发现问题?还有其他工具可以检测这些问题吗?
根据进一步的评论,我修改了缓冲区溢出功能,以便被Electric Fence检测到。但是,电围栏无法检测到这个问题。这是修改后的功能。
void buffer_overflow(void)
{
#if 0
int t[5];
int i = 0;
for(i = 0; i<=7; i++)
{
t[i] = i;
}
#endif
char *t = malloc(sizeof(char)*7);
strcpy(t,"SHREYAS_JOSHI");
/** this will cause buffer overflow **/
printf("Memory_overflow_completed\r\n");
free(t);
}
[joshis1@localhost blogs-tune2wizard]$ gcc -g buggy.c -o buggy.out -lefence
[joshis1@localhost blogs-tune2wizard]$ ./buggy.out
Electric Fence 2.2.2 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
Memory_overflow_completed
电围栏没有发现任何错误,但Valgrind至少表现出来了。
答案 0 :(得分:11)
Valgrind受限于只提供二进制文件。如果您不介意在代码中插入一些工具(通过编译器),您可以尝试address sanitizer。它会限制分配区域(甚至是堆栈)的内存,然后检查每次读/写,因此它有更高的机会来捕获这些问题。
它集成在当前的gcc(4.8+)和clang(3.2+)中 只需编译您的代码,如:
gcc -g buggy.c -o buggy.out -fsanitize=address
执行时,会输出如下内容:
==26247== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff9fa0be54 at pc 0x4008df bp 0x7fff9fa0be00 sp 0x7fff9fa0bdf8
WRITE of size 4 at 0x7fff9fa0be54 thread T0
和堆栈跟踪。
Chandler Carruth在this talk at GN13
中谈到了这个问题 注意:即使在clang 3.1中也支持它,但该开关被称为-faddress-sanitizer
而不是-fsanitize=address
。
答案 1 :(得分:2)
运行valgrind --tool=exp-sgcheck ./buggy.out
,它应该能够检测到局部变量t[5]
中有缓冲区溢出
答案 2 :(得分:0)
Valgrind和EF检测动态分配的内存中的错误。您的数组未动态分配。
答案 3 :(得分:0)
引用valgrind quick start guide:“例如,它无法检测到静态或堆栈上分配的数组的超出范围读取或写入。”
答案 4 :(得分:0)
要检测静态分配的内存(即堆栈中)的越界访问,可以使用静态代码分析工具。
我们刚刚开始在工作中使用的是Klocwork
如Valgrind wiki page所述(在memcheck的限制下),它无法检测静态分配内存的超出访问。 引自维基:
已经编写了实验性的valgrind工具exp-sgcheck来解决Memcheck中的这个限制。如果第一次访问数组在数组范围内,它将检测数组溢出错误。