addressSanitizer:地址上的堆缓冲区溢出

Lin*_*yen 7 c heap memory-leaks buffer-overflow

我刚开始学习C。

我试图编写一个函数来打开文件,读取BUFFER_SIZE,将内容存储在数组中,然后跟踪字符'\n'(因为我想获取输入的每一行)。

当我设置BUFFER_SIZE非常大时,我可以得到第一行。当我将BUFFER_SIZE合理的小数值(例如42)设置为第一行的末尾时,它会在末尾打印出一些奇怪的符号,但我猜这是我自己的代码中的一个错误。

但是,当我将其设置得BUFFER_SIZE非常小时,例如= 10,然后使用-fsanitizer=address来检查内存泄漏。它抛出错误的怪物:

==90673==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000fb at pc 0x000108868a95 bp 0x7fff573979a0 sp 0x7fff57397998
READ of size 1 at 0x6020000000fb thread T0
Run Code Online (Sandbox Code Playgroud)

如果有人可以从一般意义上解释我:

  • 什么是fsanitizer =地址标记?

  • 什么是堆缓冲区溢出?

  • 什么是地址和线程?在屏幕上以彩色显示线程的标志是什么?

  • 以及为什么它说“在地址读取大小为1。”?

我真的很感激<3

SHR*_*SHR 6

什么是fsanitizer =地址标记?

通常,C编译器不会为内存访问添加边界检查。有时由于代码错误,从缓冲区外部进行读取或写入,通常很难检测到这种错误。使用此标志,编译器将添加一些边界检查,以确保您不会使用缓冲区来超出其分配范围。

什么是堆缓冲区溢出?

使用数组在分配后到达

char* x = malloc(10);
char n=x[11]; //heap-buffer-overflow
Run Code Online (Sandbox Code Playgroud)

(下溢要在分配之前达到)

char* x = malloc(10);
char n=x[-11]; //heap-buffer-underflow
Run Code Online (Sandbox Code Playgroud)

什么是地址和线程?

地址是内存中的位置,线程是代码运行过程的一部分。

以及为什么它说“在地址读取大小为1。”?

这意味着您从给定地址读取单个字节。


我认为您的问题是您BUFFER_SIZE为缓冲区分配并将其读BUFFER_SIZE入缓冲区。正确的方法是始终声明至少比读取的字节多一个字节。像这样:

char* buff = malloc(BUFFER_SIZE+1);//notice to +1
fread(buff,1,BUFFER_SIZE,fp);
Run Code Online (Sandbox Code Playgroud)

  • 数组通常不位于堆上;它要么在堆栈上,要么在 bss 中,具体取决于它声明的范围。堆空间通常由“malloc()”分配 (2认同)
  • C 中的这个错误是常绿的:DI 从我几年前遇到的这个问题中获得了稳定的业力点流 ^^ (2认同)

Sum*_*oor 5

简单来说,它是使用 new 关键字创建的变量的分段错误,因为所有进入内存的堆区域。

解释- 您正在尝试访问尚未声明变量的地址,以查找所有此类错误,重新访问所有条件并检查您是否正在访问越界的内容。