【问题标题】:What is the use of -fno-stack-protector?-fno-stack-protector 有什么用?
【发布时间】:2012-05-29 14:09:25
【问题描述】:

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

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

【问题讨论】:

    标签: c buffer stack-overflow protection callstack


    【解决方案1】:

    在标准/标准 GCC 中,堆栈保护器默认关闭。但是,一些 Linux 发行版已对 GCC 进行了修补以默认将其打开。在我看来,这是相当有害的,因为它破坏了编译任何未链接到标准用户空间库的内容的能力,除非 Makefile 专门禁用堆栈保护器。它甚至会破坏 Linux 内核构建,只是带有这种 hack 的发行版向 GCC 添加了额外的 hack,以检测内核正在构建并禁用它。

    【讨论】:

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

    如果您使用-fstack-protector 进行编译,那么在代码设置检查然后实际检查您是否“ ve 在函数中覆盖了堆栈。

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

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

    【讨论】:

    • -fstack-protector 还重新排列堆栈布局,以便更容易检测到粉碎。
    • @jww 是的,我观察到字符串 (char[]) 的内存是在任何其他整数之前分配的。因此溢出它不会覆盖整数。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      • 当您使用的构建系统可能具有您想要调整的复杂配置时。与其弄清楚它可能选择使用fstack-protector(例如)在迷宫般的makefile中的哪个位置,它可以让您轻松地传递其他选项,这些选项只是被添加到选项列表的末尾。如果 GCC 在选项集中同时看到 fstack-protectorfno-stack-protector,则命令行中的最后一个是生效的。

      • 1234563例如,设置 -O2 会打开大量 -fxxx 优化选项,您可能希望在大多数情况下使用 -O2,但不希望 GCC 的严格别名优化。因此,您可以指定 -fno-strict-aliasing 将该特定选项设置回其默认设置。 (注:这个案例其实和上面的案例是等价的)

      【讨论】:

        【解决方案5】:

        可能想要关闭此功能的三个原因,

        • 您正在构建一个共享库,这可能很重要,其他函数会对堆栈做出假设。
        • 您担心性能。
        • 您想要构建易受攻击的软件。这种情况经常发生在 Capture The Flag (CTF) 之类的情况下,例如,如果您想构建 Protostar 来展示一个您也不会容易受到攻击的漏洞利用。

        【讨论】:

          猜你喜欢
          • 2012-03-23
          • 1970-01-01
          • 2019-09-22
          • 1970-01-01
          • 2014-05-24
          • 1970-01-01
          • 2019-06-14
          • 1970-01-01
          相关资源
          最近更新 更多