为什么地址清理器对 bss 全局溢出不起作用?

2024-05-02

我做了什么。

Test1

  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 $

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 
...

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

Update:

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

$ 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.

这是在FAQ https://github.com/google/sanitizers/wiki/AddressSanitizer#faq:

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

A1:如果你的错误太明显,编译器可能已经 在 Asan 运行时对其进行了优化。

A2:另一个仅限 C 的选项是访问全局通用符号 不受 Asan 保护(您可以使用 -fno-common 禁用常见符号的生成并希望检测更多错误)。

您的案例可能包含在 A2 中,因此添加-fno-common应该有帮助。

常见符号(默认情况下为零初始化全局变量生成)的问题在于,由于其奇怪的遗留语义,Asan 无法为它们插入 redzones(请参阅海湾合作委员会 #55739 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55739血淋淋的细节)。通过提供-fno-common您禁用公共符号的生成,而是要求 GCC 在所有情况下生成正常的全局符号(这有很小的机会破坏依赖公共符号行为的不良程序,但通常这不是问题)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么地址清理器对 bss 全局溢出不起作用? 的相关文章

随机推荐