【问题标题】:difference between gcc -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2gcc -D_FORTIFY_SOURCE=1 和 -D_FORTIFY_SOURCE=2 之间的区别
【发布时间】:2012-11-11 03:16:30
【问题描述】:

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

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

欢迎提供有关此文件记录位置的任何提示!

【问题讨论】:

  • 不确定您是否见过这些: (1) 包含 GCC 对此支持的补丁(包含=1=2 之间差异的一些细节)是here; (2) 带有关于_FORTIFY_SOURCE 条目的“功能测试宏”手册页是here

标签: security gcc glibc


【解决方案1】:

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

_FORTIFY_SOURCE(自 glibc 2.3.4 起)

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

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

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

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

使用此宏需要编译器支持,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 更安全,但编译策略风险稍高;如果您使用它,请确保您对编译后的代码进行了非常强大的回归测试,以证明编译器没有引入任何意外行为。

【讨论】:

  • 是否有任何迹象表明符合标准的程序何时可能失败?
  • -D_FORTIFY_SOURCE=1 添加至少一个运行时检查:它允许使用__longjmp_chk 而不是__longjmp,前者检查您不会在堆栈中“向下”跳转。
  • “2 级更安全,但风险稍高” — 听起来有风险的是潜在的溢出;假设您的软件没有缓冲区溢出的代码,那么级别 2 是否不符合?
【解决方案2】:

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,%n 在最常见的*printf 系列函数的格式字符串中 仅当它存储在只读存储器中时才被允许(通常 字符串文字,gettext_("%s string %n") 也可以),但是 通常当攻击者试图利用格式字符串时 漏洞,%n 将位于攻击者可能的位置 写进去。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多