77

有人能指出gcc -D_FORTIFY_SOURCE=1和之间的区别-D_FORTIFY_SOURCE=2吗?我想=2是不是更安全?我一直无法找到逐点列出差异的列表。

我还阅读了-D_FORTIFY_SOURCE=2应该与 一起使用的内容-O2,否则并非所有功能都可用。同样在这里,我还没有找到详细说明回归的列表。我特别有兴趣编译,-Os因为目标是没有那么多闪存的设备。

欢迎任何关于记录在哪里的提示!

4

2 回答 2

67

来自功能测试宏的手册页 ( man 7 feature_test_macros)

_FORTIFY_SOURCE(从 glibc 2.3.4 开始)

定义此宏会导致在使用各种字符串和内存操作函数(例如memcpy,、、、、、、、、、、、、、、、、及其宽字符变体)时 memset执行一些stpcpy轻量级检查以检测一些缓冲区溢出错误。对于某些函数,会检查参数的一致性;例如,当指定的标志包括. 并非所有问题都被检测到,只是一些常见情况。strcpystrncpystrcatstrncatsprintfsnprintfvsprintfvsnprintfgetsopenO_CREAT

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

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

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

使用此宏需要编译器支持,gcc从 4.0 版开始提供。

此外,文章Enhance application security with FORTIFY_SOURCE(2014 年 3 月)说:

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

本质上,_FORTIFY_SOURCE级别 2 更安全,但编译策略风险稍高;如果您使用它,请确保您对编译后的代码进行了非常强大的回归测试,以证明编译器没有引入任何意外行为。

于 2013-05-17T07:55:44.330 回答
25

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.htmlfeature_test_macros(7).

这是相关的摘录,为了清晰起见,经过轻微编辑/重新格式化:

-D_FORTIFY_SOURCE=1和之间的区别-D_FORTIFY_SOURCE=2 是例如

  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只有当它存储在只读内存中(通常是字符串文字,'s也可以)时,才允许%n 使用最常见系列函数的格式字符串,但通常当攻击者试图利用格式字符串时漏洞,将在攻击者可以写入的地方。*printfgettext_("%s string %n")%n

于 2017-08-01T18:46:51.883 回答