我用 C 编写了一个应用程序,我试图了解-fno-stack-protector
编译时命令的目的是什么。对于我的特定应用程序,是否使用此命令在防止缓冲区溢出方面没有区别。
我在网上读到-fstack-protector
and-fno-stack-protector
命令分别启用和禁用堆栈粉碎保护器,但是如果我自己编译应用程序,如何事先启用保护器?该命令的使用是否可能取决于应用程序运行的系统?
我用 C 编写了一个应用程序,我试图了解-fno-stack-protector
编译时命令的目的是什么。对于我的特定应用程序,是否使用此命令在防止缓冲区溢出方面没有区别。
我在网上读到-fstack-protector
and-fno-stack-protector
命令分别启用和禁用堆栈粉碎保护器,但是如果我自己编译应用程序,如何事先启用保护器?该命令的使用是否可能取决于应用程序运行的系统?
在标准/库存 GCC 中,堆栈保护器默认关闭。但是,一些 Linux 发行版已对 GCC 进行了修补以默认将其打开。在我看来,这是相当有害的,因为它破坏了编译任何未链接到标准用户空间库的内容的能力,除非 Makefile 专门禁用堆栈保护器。它甚至会破坏 Linux 内核构建,只是带有此 hack 的发行版向 GCC 添加了额外的 hack,以检测内核正在构建并禁用它。
如果您使用 编译-fstack-protector
,那么在代码设置检查然后实际检查您是否已覆盖堆栈时,堆栈上将分配更多空间,并且在进入和返回函数时会产生更多开销功能。
它将对您的应用程序产生影响。如果启用,它将快速阻止堆栈溢出攻击。只有当您的代码中没有函数调用时,它才会使您的程序不受影响(并且由于您通常编写main()
, 并且这是一个由启动代码调用的函数,它会对您的程序产生影响)。但是,堆栈溢出攻击并不是唯一可以使用的攻击,因此它不是万能的。但它是有用的保护,成本有限。
保护不依赖于系统本身;这取决于您使用的编译器的版本,仅此而已。
堆栈保护器是由编译器生成并放入您的程序的代码。它不是您的程序调用的外部程序或系统调用。
匹配默认编译器设置的选项可能有用的时间包括:
当您使用的构建系统可能具有您想要调整的复杂配置时。它可以让您轻松地传递附加选项,而不是弄清楚它可能会选择在迷宫中的哪个位置使用fstack-protector
(例如),这些选项只会被添加到选项列表的末尾。如果 GCC 在这组选项中都看到fstack-protector
和fno-stack-protector
,则命令行中的最后一个是生效的。
另一次这种事情可能很方便(然而,这似乎不适用于-fstack-protector
)是当您有一个选项可以打开一堆“子选项”时。例如,设置 -O2 会打开一系列-fxxx
优化选项,您可能希望-O2
大部分使用但不希望 GCC 的严格别名优化。因此,您可以指定-fno-strict-aliasing
将该特定选项设置回其默认设置。(注:这个案例真的和上面的案例是等价的)
您可能要关闭此功能的三个原因,