C fno堆栈保护器的用途是什么?

C fno堆栈保护器的用途是什么?,c,buffer,stack-overflow,protection,callstack,C,Buffer,Stack Overflow,Protection,Callstack,我已经用C编写了一个应用程序,我试图理解编译时-fno stack protector命令的用途。对于我的特定应用程序,在防止缓冲区溢出方面,是否使用此命令没有任何区别 我在网上读到,-fstack-protector和-fno-stack-protector命令分别启用和禁用stack-smashing-protector,但是如果我自己编译应用程序,如何事先启用保护程序?命令的使用是否可能取决于应用程序运行在哪个系统上?在标准/stock GCC中,默认情况下stack protector处

我已经用C编写了一个应用程序,我试图理解编译时
-fno stack protector
命令的用途。对于我的特定应用程序,在防止缓冲区溢出方面,是否使用此命令没有任何区别


我在网上读到,
-fstack-protector
-fno-stack-protector
命令分别启用和禁用stack-smashing-protector,但是如果我自己编译应用程序,如何事先启用保护程序?命令的使用是否可能取决于应用程序运行在哪个系统上?

在标准/stock GCC中,默认情况下stack protector处于关闭状态。然而,一些Linux发行版已经修补了GCC,以在默认情况下打开它。在我看来,这是相当有害的,因为它破坏了编译任何未与标准用户空间库链接的内容的能力,除非Makefile专门禁用堆栈保护器。它甚至会破坏Linux内核的构建,除了带有此漏洞的发行版向GCC添加了额外的漏洞,以检测正在构建的内核并禁用它。

如果使用
-fstack-protector
编译,然后,当代码设置检查,然后实际检查在函数中是否覆盖堆栈时,堆栈上会分配多一点空间,函数的输入和返回会有多一点开销

这将对你的申请产生影响。如果启用,它将快速阻止堆栈溢出攻击。只有在代码中没有函数调用时,它才会使程序不受影响(而且由于您通常编写
main()
,而这是一个由启动代码调用的函数,因此它会对程序产生影响)。但是,堆栈溢出攻击不是唯一可以使用的攻击,因此它不是万灵药。但它是有用的保护,成本有限


保护不依赖于系统本身;这取决于您使用的编译器版本,但仅此而已。

堆栈保护器是由编译器生成并放入程序中的代码。它不是由您的程序调用的外部程序或系统调用。

与默认编译器设置匹配的选项可能有用的时候包括:

  • 当您使用的构建系统可能具有您想要调整的复杂配置时。例如,它可以让您轻松地将附加选项传递到选项列表的末尾,而不是在迷宫般的makefile中找出它可能选择使用
    fstack protector
    (例如)的位置。如果GCC在选项集中同时看到
    fstack protector
    fno stack protector
    ,则命令行上的最后一个选项将生效


  • 另一种情况是,当您有一个选项打开一组“子选项”时,这种方法可能会很方便(这似乎不适用于
    -fstack-protector
    )。例如,设置-O2会打开大量的
    -fxxx
    优化选项,您可能希望在大多数情况下使用
    -O2
    ,但不希望GCC严格的别名优化。因此,您可以指定
    -fno strict aliasing
    ,将特定选项设置回其默认设置。(注:本案例与上述案例相当)


    • 您可能希望关闭此功能的原因有三个:

      • 您正在构建一个共享的a库,在这个库中这可能很重要,其他函数会对堆栈进行假设
      • 你关心的是表现
      • 您想要构建易受攻击的软件。这种情况经常发生在捕获标志(CTFs)之类的情况下,比如如果您想构建Protostar来演示一种利用漏洞,否则您也不会受到攻击

      根据定义,在默认情况下启用堆栈保护的系统上编译的任何东西都不会与使用堆栈保护构建的库相链接,因为它们反过来会在启用堆栈保护的系统上编译吗?我假设您正在处理我回答的第二部分(关于为什么会有问题的评论)如果是这样,那么答案是否定的。任何不打算作为主机用户空间生态系统的一部分运行的代码都不会与主机的任何库相链接。(例如,内核不与任何用户空间库相链接。其他示例包括引导加载程序代码、dynrec/JIT仿真器打算读入并用作模板的模块等)并不是在谈论内核空间,而是用户空间;JIT编译不是用C编译器完成的;因此,我不得不问,除了可能必须在linux内核的编译参数中设置“-fno stack protector”之外,在userland中启用堆栈保护还有什么问题?我的JIT示例是,可以编写JIT在C中使用的代码单元,而不是为每个可能的ISA编写代码生成逻辑,编译成ELF
      .o
      文件,并将它们用作JIT在最少的ISA特定知识下组装的数据。也许你不喜欢我的例子,但一个人肯定会想出其他的例子。基本上,在将编译器作为独立实现使用的任何情况下,堆栈保护器都是错误的(尽管可以通过省略
      -lssp
      并提供自己的
      \uu stack\u chk\u fail
      使其工作)。我的观点是,它迫使每一个使用C编译器作为独立实现的程序都包含逻辑,以检查ssp在默认情况下是否打开,以及如何将其关闭到构建系统。下一次发行版对默认GCC配置进行攻击时,同样的问题也会重复。如果
      -ff重建
      在默认情况下阻止ssp打开,那么它就不会这样