有人能指出gcc -D_FORTIFY_SOURCE=1
和-D_FORTIFY_SOURCE=2
之间的区别吗?我猜=2
更安全?我还没有找到一个逐点列出不同之处的列表。
我还读到,-D_FORTIFY_SOURCE=2
应该与-O2
一起使用,否则并不是所有的功能都可用。另外,我还没有找到详细说明回归的列表。我特别有兴趣用-Os
编译,因为目标是一个没有那么多闪存的设备。
任何关于这方面的提示都是欢迎的!
发布于 2013-05-17 15:55:44
从功能测试宏(man 7 feature_test_macros
)的手册页
_FORTIFY_SOURCE
(从glibc 2.3.4开始)
定义此宏会导致在使用各种字符串和内存操作函数(例如,memcpy
、memset
、stpcpy
、strcpy
、strncpy
、strcat
、strncat
、sprintf
、snprintf
、vsprintf
、vsnprintf
、gets
及其宽字符变体)时执行一些轻量级检查,以检测某些缓冲区溢出错误。对于某些函数,会检查参数一致性;例如,当指定的标志包括O_CREAT
.时,会检查是否已向open
提供了模式参数并不是所有的问题都被检测到,只是一些常见的情况。
如果使用编译器优化级别1 (gcc -O1
)或更高级别将_FORTIFY_SOURCE
设置为1,则将执行不应更改符合要求的程序的行为的检查。
将_FORTIFY_SOURCE
设置为2时,会添加更多检查,但一些符合要求的程序可能会失败。
一些检查可以在编译时执行(通过在头文件中实现的宏逻辑),并导致编译器警告;另一些检查在运行时进行,如果检查失败,则会导致运行时错误。
使用此宏需要编译器支持,从4.0版开始,gcc
就提供了编译器支持。
此外,文章Enhance application security with FORTIFY_SOURCE (2014年3月)说:
gcc -D_FORTIFY_SOURCE=1
仅在编译时添加检查(某些标头是必需的,因为#include <string.h>
)gcc -D_FORTIFY_SOURCE=2
还会在运行时添加检查(检测到缓冲区溢出会终止程序)从本质上讲,_FORTIFY_SOURCE
级别2更安全,但也是一种风险稍高的编译策略;如果您使用它,请确保您对编译后的代码进行了非常强大的回归测试,以证明编译器没有引入任何意外的行为。
发布于 2017-08-02 02:46:52
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html比feature_test_macros(7)
更详细。
以下是相关摘录,为清晰起见,略有编辑/重新格式化:
-D_FORTIFY_SOURCE=1
和-D_FORTIFY_SOURCE=2
之间的区别是
结构S{结构T{ char buf5;int x;} t;char buf20;} var;
使用-D_FORTIFY_SOURCE=1
,
strcpy (&var.t.buf1,"abcdefg");
不会被视为溢出(object是整个var
),而使用-D_FORTIFY_SOURCE=2
strcpy (&var.t.buf1,"abcdefg");
将被视为缓冲区溢出。
另一个不同之处在于,对于-D_FORTIFY_SOURCE=2
,最常见的*printf
系列函数的格式字符串中的%n
只有在存储在只读内存中时才被允许(通常是字符串文字,gettext
的_("%s string %n")
也可以),但通常当攻击者试图利用格式字符串漏洞时,%n
将是攻击者可以将其写入的地方。
https://stackoverflow.com/questions/13517526
复制相似问题