为什么地址消毒剂对bss全局溢出不起作用?

Ale*_*pus 9 c memory-management buffer-overflow address-sanitizer

我做了什么.

测试1

  1 #include <stdio.h>                                                              
  2                                                                                 
  3 int test[16];                                                                   
  4                                                                                 
  5 int main()                                                                      
  6 {                                                                               
  7     test[17] = -1;                                                              
  8 } 

/tmp $ gcc ./main.c -o main -fsanitize=address
/tmp $ ./main 
/tmp $
Run Code Online (Sandbox Code Playgroud)

TEST2

  1 #include <stdio.h>                                                              
  2                                                                                 
  3 int test[16] = {1};                                                             
  4                                                                                 
  5 int main()                                                                      
  6 {                                                                               
  7     test[17] = -1;                                                              
  8 }

 /tmp $ gcc ./main.c -o main -fsanitize=address
 /tmp $ ./main 

=================================================================
==19776==ERROR: AddressSanitizer: global-buffer-overflow on address 
...
Run Code Online (Sandbox Code Playgroud)

看起来全局缓冲区溢出检测不适用于放在bss中的全局变量(是这样吗?).这背后的原因是什么?

更新:

存储的代码没有优化.系统信息:

$ gcc --version
gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)

yug*_*ugr 6

这是在FAQ中:

问:为什么ASan在我的代码中没有报告明显无效的内存访问?

A1:如果您的错误太明显,编译器可能已经在Asan运行时优化了它.

A2:另一个只有C的选项是访问不受Asan保护的全局公共符号(您可以使用-fno-common来禁用公共符号的生成并希望检测更多错误).

您的案件很可能由A2涵盖,因此添加-fno-common应该有所帮助.

常见符号(默认情况下为零初始化全局变量生成)的问题在于,由于其奇怪的遗留语义,Asan无法为它们插入redzones(有关血淋淋的详细信息,请参阅GCC#55739).通过为-fno-common您提供禁用公共生成,而是要求GC​​C在所有情况下生成正常的全局符号(这很可能会破坏依赖于常见符号行为的错误编写的程序,但通常不是问题).