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

时间:2018-04-19 16:16:02

标签: 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 $

的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中的全局变量(是这样吗?)。这背后的原因是什么?

更新

存储的代码未优化。 系统信息:

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

2 个答案:

答案 0 :(得分:6)

这是FAQ

  

问:为什么ASan报告我的内存访问明显无效   码?

     

A1:如果您的错误太明显,编译器可能已经存在   在Asan跑步的时候对它进行了优化。

     

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

您的情况很可能由A2涵盖,因此添加-fno-common会有所帮助。

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

答案 1 :(得分:-2)

其他工具,包括我们的(语义设计)CheckPointer工具,可以做到这一点。 (编辑输出以删除一些不相关的文本):

对于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

对于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不需要围绕数据“redzones”;它检查对语言语义的访问。这意味着,例如,它将检测结构中任何位置的char数组末尾的访问,无论结构是本地(堆栈)变量,还是堆中,线程本地存储中,还是嵌入在某些其他结构中。 / p>

与“CWE-119”相关的“奇怪的措辞”不是我们选择的单词,它由Common Weakness Enumeration的标准定义。 CheckPointer使用CWE定义,分类和描述报告错误。