简体   繁体   English

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

[英]Why address sanitizer doesn't work for bss global overflow?

What I have done. 我做了什么。

Test1 测试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 $

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

Looks like global buffer overflow detection is not working for global variables which are placed in bss (is it so?). 看起来全局缓冲区溢出检测不适用于放在bss中的全局变量(是这样吗?)。 What are the reasons behind this? 这背后的原因是什么?

Update: 更新:

The code which does store is not optimized out. 存储的代码没有优化。 System information: 系统信息:

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

This is in FAQ : 这是在FAQ中

Q: Why didn't ASan report an obviously invalid memory access in my code? 问:为什么ASan在我的代码中没有报告明显无效的内存访问?

A1: If your errors is too obvious, compiler might have already optimized it out by the time Asan runs. A1:如果您的错误太明显,编译器可能已经在Asan运行时优化了它。

A2: Another, C-only option is accesses to global common symbols which are not protected by Asan (you can use -fno-common to disable generation of common symbols and hopefully detect more bugs). A2:另一个只有C的选项是访问不受Asan保护的全局公共符号(您可以使用-fno-common来禁用公共符号的生成并希望检测更多错误)。

Your case is probly covered by A2 so adding -fno-common should help. 您的案例很可能由A2涵盖,因此添加-fno-common应该有所帮助。

The issue with common symbols (which are generated for zero-initialized global variables by default) is that, due to their weird legacy semantics, Asan can not insert redzones for them (see GCC #55739 for gory details). 常见符号(默认情况下为零初始化全局变量生成)的问题在于,由于其奇怪的遗留语义,Asan无法为它们插入redzones(有关血淋淋的详细信息,请参阅GCC#55739 )。 By supplying -fno-common you disable generation of commons and instead ask GCC to generate normal global symbols in all cases (this has a small chance of breaking ill-written programs that rely on common symbols behavior but usually it's not an issue). 通过提供-fno-common您可以禁用公共的生成,而是要求GC​​C在所有情况下生成正常的全局符号(这很可能会破坏依赖于常见符号行为的错误编写的程序,但通常不是问题)。

Other tools, including our (Semantic Designs) CheckPointer tool, do this. 其他工具,包括我们的(语义设计)CheckPointer工具,可以做到这一点。 (Output edited to remove some irrelevant text): (编辑输出以删除一些不相关的文本):

For test1.c as OP defined it: 对于test1.c,OP定义它:

c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source>DMSCheckPointer C~GCC4 test1.c
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential

c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source>gcc.exe -I"c:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -otest1.exe Target\test1.c <snip>

test1
*** Error: CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
       Dereference of pointer is out of bounds.
in function: main, line: 7, file c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source\test1.c

For test2.c: 对于test2.c:

c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source>DMSCheckPointer C~GCC4 test2.c
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential

c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source>gcc.exe -I"c:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -otest2.exe Target\test2.c <snip>

test2
*** Error: CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
       Dereference of pointer is out of bounds.
in function: main, line: 7, file c:\DMS\Domains\C\GCC4\Tools\CheckPointer\Example\Source\test2.c

CheckPointer doesn't need "redzones" around data; CheckPointer不需要围绕数据的“redzones”; it checks accesses against the language semantics. 它检查对语言语义的访问。 That means it will, for example, detect accesses off the end of a char array anywhere in a struct, whether the struct is a local (stack) variable, in the heap, in thread local storage, or embedded in some other structure. 这意味着,例如,它将检测结构中任何位置的char数组末尾的访问,无论结构是本地(堆栈)变量,堆中,线程本地存储中,还是嵌入在某些其他结构中。

The "odd phrasing" related to "CWE-119" isn't our choice of words, it is defined by the standard for Common Weakness Enumeration . 与“CWE-119”相关的“奇怪的措辞”不是我们选择的单词,它由Common Weakness Enumeration的标准定义。 CheckPointer reports errors using the CWE definitions, classifications and descriptions. CheckPointer使用CWE定义,分类和描述报告错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM