为什么电栅栏/ Valgrind无法捕获这个缓冲区溢出问题?

时间:2013-10-06 10:25:01

标签: c++ c memory-leaks valgrind electric-fence

我创建了一个错误的程序 - 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至少表现出来了。

5 个答案:

答案 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中的这个限制。如果第一次访问数组在数组范围内,它将检测数组溢出错误。