4

我创建了一个有问题的程序 - 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 withelectric 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

Electric Fence 没有检测到错误,但 Valgrind 至少显示了它。

4

5 回答 5

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在 GN13的这次演讲中谈到了它

注意:即使在 clang 3.1 中也支持它,但调用的是 switch-faddress-sanitizer而不是-fsanitize=address.

于 2013-10-06T12:34:41.707 回答
3

正在运行valgrind --tool=exp-sgcheck ./buggy.out,它应该能够检测到您在局部变量中存在缓冲区溢出t[5]

于 2013-10-07T05:51:51.757 回答
0

Valgrind 和 EF 检测动态分配内存中的错误。您的数组不是动态分配的。

于 2013-10-06T10:27:15.587 回答
0

引用 valgrind快速入门指南:“例如,它无法检测对静态分配或堆栈上的数组的超出范围的读取或写入。”

于 2013-10-06T11:11:41.437 回答
0

要检测静态分配的内存(即堆栈上)的越界访问,您可以使用静态代码分析工具。

我们刚刚开始在工作中使用的一种是Klocwork

正如Valgrind wiki 页面上提到的(在 memcheck 的限制下),它无法检测到静态分配内存的越界访问。引用维基:

已编写实验性 valgrind 工具 exp-sgcheck 以解决 Memcheck 中的此限制。如果对数组的第一次访问在数组范围内,它将检测数组溢出错误。

于 2013-10-08T16:59:54.857 回答