67

-Wstack-protector在编译我正在处理的项目(商业多平台 C++ 游戏引擎,在 Mac OS X 10.6 和 GCC 4.2 上编译)时启用了警告。此标志警告即使-fstack-protector启用,也无法防止堆栈粉碎的功能。GCC 在构建项目时会发出一些警告:

不保护函数:没有至少 8 字节长的缓冲区
不保护局部变量:可变长度缓冲区

对于第一个警告,我发现可以调整缓冲区在函数中使用时必须具有的最小大小,以便保护该函数免受堆栈粉碎:--param ssp-buffer-size=X可以使用,其中 X 默认为 8,可以为低至 1。

对于第二个警告,除非我停止使用-Wstack-protector.

  1. 什么时候应该-fstack-protector使用?(例如,在开发期间的所有时间,或者只是在跟踪错误时?)
  2. 什么时候应该-fstack-protector-all使用?
  3. -Wstack-protector告诉我什么?是否建议我减小缓冲区最小大小?
  4. 如果是这样,将大小设置为 1 有什么缺点吗?
  5. 如果您想要一个无警告的构建,这似乎-Wstack-protector不是您想要始终启用的那种标志。这是正确的吗?
4

2 回答 2

74

堆栈保护是一种强化策略,而不是调试策略。如果您的游戏具有网络感知功能或其他数据来自不受控制的来源,请将其打开。如果它没有来自不受控制的地方的数据,请不要打开它。

其结果如下:如果您有错误并根据攻击者可以控制的内容更改缓冲区,则攻击者可以覆盖返回地址或堆栈的类似部分,以使其执行其代码而不是您的代码。如果堆栈保护检测到这种情况发生,它将中止您的程序。您的用户不会高兴,但他们也不会被黑客入侵。这不是关于在游戏中作弊的黑客行为,而是关于某人利用您的代码中的漏洞创建可能感染您的用户的漏洞的黑客行为。

对于面向调试的解决方案,请查看诸如 mudflap 之类的东西。

至于你的具体问题:

  1. 如果您从不受控制的来源获取数据,请使用堆栈保护器。这个问题的答案很可能是肯定的。所以使用它。即使您没有来自不受控制的来源的数据,您也可能最终或已经拥有并且没有意识到这一点。
  2. 如果您想要额外的保护以换取一些性能损失,可以使用所有缓冲区的堆栈保护。从gcc4.4.2 手册

    -fstack-保护器

    发出额外的代码来检查缓冲区溢出,例如堆栈粉碎攻击。这是通过将保护变量添加到具有易受攻击对象的函数来完成的。这包括调用 alloca 的函数,以及缓冲区大于 8 字节的函数。进入函数时初始化守卫,然后在函数退出时检查。如果保护检查失败,则会打印一条错误消息并退出程序。

    -fstack-保护器-所有

    与 -fstack-protector 类似,只是所有函数都受到保护。

  3. 警告告诉您堆栈保护无法保护的缓冲区。

  4. 这并不一定建议您减小最小缓冲区大小,并且在大小为 0/1 时,它与 stack-protector-all 相同。如果您决定重新设计代码以保护缓冲区,它只是向您指出,以便您可以。
  5. 不,这些警告并不代表问题,它们只是向您指出信息。不要经常使用它们。
于 2010-11-25T19:46:23.657 回答
1

您确实不应该关心正常构建的警告。这实际上更像是一条信息性消息。我希望很明显,您确实对堆栈上的可变大小缓冲区存在固有的安全问题;尺寸计算错误,你打开了一个大洞。

于 2009-10-27T10:15:29.047 回答