我正在学习地址清理程序:
#include <stdio.h>
int main(int argc, char **argv)
{
int array[30]={0};
(void) printf("%d\n", array[179]); // <--- should crash, right?
return 0;
}
但我无法触发任何错误/警告:
$ gcc -c main.c -fsanitize=address -o main.o
$ gcc main.o -fsanitize=address -o main
$ ./main
32765
1条答案
按热度按时间xesrikrc1#
在
-fsanitize=address
的情况下,使用有限大小的影子存储器检查存储器访问,其中堆栈缓冲区由两个红色区域包围(一个在缓冲区之前,一个在缓冲区之后)。如果访问发生在红色区域内,Asan会检测到错误并中止执行。但是,这些红色区域非常小,因为它们是设计用于检测缓冲区溢出/溢出错误的。而不是具有大索引的野生越界访问。你的情况是这样的:
而且错误的内存读取也不会被检测到。
您要检测的此类错误是
-fsanitize=undefined
,或者更具体地说是-fsanitize=bounds
或-fsanitize=bounds-strict
之一。在这种情况下,边界检查将考虑数组的定义,并针对通过其标识符进行的每次访问检查其类型和边界。但请注意,这通常不会保存您执行以下操作:
因为在这种情况下,
arr
的边界在函数foo
中是未知的。或者,您也可以考虑manually poisoning阴影内存:
然而这也有它的局限性,因为你应该避免毒害堆栈上的其他缓冲区/变量。在上面的简单例子中,做这样一个大的手动毒害是可以的,但不是一般的。