gcc -D_FORTIFY_SOURCE = 1和-D_FORTIFY_SOURCE = 2之间的差异

有人能指出gcc -D_FORTIFY_SOURCE = 1和-D_FORTIFY_SOURCE = 2之间的区别吗? 我猜= 2更安全? 我一直没能find一个逐点列出差异的清单。

我也读过-D_FORTIFY_SOURCE = 2应该和-O2一起使用,否则不是所有的function都可用。 在这里,我还没有find一个列表,详细说明回归。 我特别希望用-Os进行编译,因为目标是一个没有太多闪存的设备。

任何提示,这是logging在案的欢迎!

从functiontestingmacros手册页( man 7 feature_test_macros

_FORTIFY_SOURCE (自glibc 2.3.4开始)

定义这个macros会导致一些轻量级的检查,当使用各种string和内存操作函数(例如, memcpymemsetstpcpystrcpystrncpystrcatstrncatsprintfsnprintfvsprintfvsnprintfgets ,并且其宽字符变体)。 对于某些函数,检查参数一致性; 例如,当指定的标志包括O_CREAT时,检查open已被提供模式参数。 不是所有的问题都被发现,只是一些常见的情况。

如果_FORTIFY_SOURCE设置为1,编译器优化级别1( gcc -O1 )及以上,则执行不应改变符合程序行为的检查。

_FORTIFY_SOURCE设置为2时,会添加更多检查,但是某些符合要求的程序可能会失败。

一些检查可以在编译时执行(通过在头文件中实现的macros逻辑),并导致编译器警告; 其他检查在运行时发生,如果检查失败将导致运行时错误。

使用这个macros需要编译器的支持,从4.0版本开始可以使用gcc

此外, 使用FORTIFY_SOURCE (2014年3月) 增强应用程序安全性的文章说:

  • gcc -D_FORTIFY_SOURCE=1仅在编译时添加检查(某些头文件是必须的,因为#include <string.h>
  • gcc -D_FORTIFY_SOURCE=2也在运行时增加检查(检测到的缓冲区溢出终止程序)

从本质上讲, _FORTIFY_SOURCE 2级更安全,但编制策略风险略高; 如果您使用它,请确保您的编译代码具有非常强大的回归testing,以certificate编译器没有引入任何意外的行为。

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html比;feature_test_macros(7)更详细。

下面是相关摘录,为了清楚起见,对其进行了轻度编辑/重新格式化:

-D_FORTIFY_SOURCE=1-D_FORTIFY_SOURCE=2之间的差异是例如for

  struct S { struct T { char buf[5]; int x; } t; char buf[20]; } var; 

使用-D_FORTIFY_SOURCE=1

  strcpy (&var.t.buf[1], "abcdefg"); 

不被视为溢出(对象是整个VAR ),而-D_FORTIFY_SOURCE=2

  strcpy (&var.t.buf[1], "abcdefg"); 

将被视为缓冲区溢出。

另一个不同之处在于,使用-D_FORTIFY_SOURCE=2 ,只有在最常见的*printf系列函数的格式化string中,只有存储在只读存储器(通常是string文本, gettext_("%s string %n")也可以),但通常当攻击者试图利用格式string漏洞时, %n将会在攻击者可以写入的地方。