GCC 编译 C/C++ 的最强化的一组选项是什么?

信息安全 缓冲区溢出 海合会 C++
2021-08-19 08:23:21

哪组 GCC 选项可针对内存损坏漏洞(如缓冲区溢出和悬空指针)提供最佳保护?GCC 是否提供任何类型的 ROP 链缓解?是否存在性能问题或其他问题会阻止此 GCC 选项用于关键任务应用程序?

我正在查看Debian Hardening GuideGCC Mudflap以下是我正在考虑的配置:

-D_FORTIFY_SOURCE=2
-fstack-protector --param ssp-buffer-size=4
-fPIE -pie
-Wl,-z,relro,-z,now (ld -z relro and ld -z now)

可以对这组选项进行任何改进吗?

我们最担心的是保护 WebKit。

2个回答

我不为 gcc 编写代码,所以希望其他人可以添加或纠正我。我会用回复编辑它。其中一些不适用于所有情况。

  • -Wall -Wextra
    打开所有警告以帮助确保底层代码是安全的。

  • -Wconversion -Wsign-conversion
    对 unsign/sign 转换发出警告。

  • -Wformat-security
    警告使用表示可能的安全问题的格式函数。

  • -Werror
    将所有警告变成错误。

  • -arch x86_64
    为 64 位编译以最大限度地利用地址空间(对于 ASLR 很重要;随机化布局时可以选择更多的虚拟地址空间)。

  • -mmitigate-rop
    尝试编译没有意外返回地址的代码,使 ROP 变得更加困难。

  • -mindirect-branch=thunk -mfunction-return=thunk
    启用retpoline(返回蹦床)以减轻 Spectre V2 的某些变体。由于分支目标缓冲区易受攻击,因此 Skylake+ 需要第二个标志。

  • -fstack-protector-all -Wstack-protector --param ssp-buffer-size=4
    您选择的“-fstack-protector”并不保护所有功能(见注释)。您需要-fstack-protector-all保证将保护应用于所有功能,尽管这可能会导致性能损失。考虑-fstack-protector-strong作为一个中间立场。
    此处的-Wstack-protector标志为任何不会受到保护的功能发出警告。

  • -fstack-clash-protection击败称为堆栈冲突
    的一类攻击

  • -pie -fPIE
    需要获得 ASLR 的全部安全优势。

  • -ftrapv
    为签名溢出生成陷阱(当前在 gcc 中存在错误,并且可能会干扰 UBSAN)

  • -D_FORTIFY_SOURCE=2
    缓冲区溢出检查。另请参阅=2 和 =1 之间的区别

  • -Wl,-z,relro,-z,now
    RELRO(只读重定位)。一起指定的选项relro&now被称为“完整 RELRO”。now您可以通过省略该标志来指定“部分 RELRO” 。RELRO 将各种 ELF 内存部分标记为只读(例如GOT)。

  • -Wl,-z,noexecstack
    非可执行堆栈。此选项将堆栈标记为不可执行,可能与许多代码不兼容,但为任何可能的代码执行提供了很多安全性。https://www.win.tue.nl/~aeb/linux/hh/protection.html
  • -fvtable-verify=[std|preinit|none]
    Vtable 指针验证。它可以在运行时对每个虚拟调用进行验证,通过它进行调用的 vtable 指针对于对象的类型是有效的,并且没有被破坏或覆盖。如果在运行时检测到无效的 vtable 指针,则会报告错误并立即停止程序的执行。(https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
  • -fcf-protection=[full|branch|return|none]
    启用控制流传输的代码检测,通过检查控制流传输指令的目标地址(例如间接函数调用、函数返回、间接跳转)来提高程序安全性是有效的。仅适用于带有英特尔 CET 的 x86(_64)。https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html

如果在 Windows 上编译,请使用 Visual Studio 而不是 GCC,因为 Windows 的某些保护(例如 SEHOP)不是 GCC 的一部分,但如果您必须使用 GCC:

  • -Wl,dynamicbase
    告诉链接器使用 ASLR 保护。
  • -Wl,nxcompat
    告诉链接器使用 DEP 保护。

这些都是不错的选择,但您需要注意自己的源代码。确保在处理用户输入时使用安全函数,过滤它们,当你使用 strncpy() 之类的东西时,尽量不要给太多空间来防止某些攻击。操作系统本身提供安全性,即 DEP (NX)、ASLR 和金丝雀来保护堆栈,但您不能一直依赖它们。所以,是的,以上是我的建议。我希望对您有所帮助,您还可以使用源代码审计工具。祝你好运!