何时以及如何使用GCC的堆栈保护function?

编译我正在编写的项目(商业多平台C ++游戏引擎,在Mac OS X 10.6上使用GCC 4.2编译)时,我启用了-Wstack-protector警告。 即使启用了堆栈保护function,该标志也会警告不会受到堆栈粉碎-fstack-protector的function。 海湾合作委员会在build设项目时发出一些警告:

不保护function:无缓冲区至less8字节长
不保护局部variables:可变长度缓冲区

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

对于第二个警告,除非我停止使用-Wstack-protector否则我不能抑制它的发生。

  1. 什么时候应该使用-fstack-protector ? (例如,在开发过程中的所有时间,或只是跟踪错误?)
  2. 什么时候应该使用-fstack-protector-all
  3. 什么是-Wstack-protector告诉我? 是否build议我减less缓冲区的最小大小?
  4. 如果是这样的话,把尺寸设置为1还有什么缺点吗?
  5. 看起来,如果你想要一个免警告的构build, -Wstack-protector并不是你想要的标志。 这是正确的吗?

堆栈保护是一种强化策略,而不是debugging策略。 如果您的游戏具有networking感知function,或者数据来自不受控制的来源,请将其打开。 如果没有来自不受控制的数据,请不要打开它。

以下是它的作用:如果你有一个bug,并根据攻击者可以控制的东西进行缓冲区更改,攻击者可以覆盖返回地址或堆栈的类似部分,使其执行代码而不是代码。 如果检测到这种情况,堆栈保护会中止程序。 你的用户不会很高兴,但他们也不会被黑客攻击。 这不是在游戏中作弊的黑客行为,而是一种黑客行为,就是有人在您的代码中使用漏洞来创build可能会感染您的用户的漏洞。

对于面向debugging的解决scheme,请看像mudflap的东西。

至于你的具体问题:

  1. 如果您从不受控制的来源获取数据,请使用堆栈保护程序。 答案可能是肯定的。 所以使用它。 即使你没有来自不受控制的来源的数据,你也许最终会或已经做了,没有意识到。
  2. 如果您想要额外的保护来换取一些性能命中,可以使用所有缓冲区的堆栈保护。 从gcc4.4.2手册 :

    -fstack保护器

    发出额外的代码来检查缓冲区溢出,如堆栈粉碎攻击。 这是通过向具有易受攻击的对象的函数添加一个guardvariables来完成的 这包括调用alloca的函数,以及缓冲区大于8字节的函数。 当一个函数被input时,守卫被初始化,然后在函数退出时被检查。 如果警卫检查失败,则会打印出错信息并退出程序。

    -fstack保护器,所有

    除了所有的function都受到保护之外,就像-fstack-protector一样。

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

  4. 这不一定build议你减less你的最小缓冲区大小,在0/1的大小,它是一样的stack-protector-all。 它只是指向你,所以你可以,如果你决定重新devise的代码,使缓冲区被保护。
  5. 不,这些警告不代表问题,他们只是向你指出信息。 不要经常使用它们。

你确实不应该关心正常构build的警告。 这实际上是更多的信息消息。 我希望很明显,你对堆栈上可变大小的缓冲区有一个固有的安全问题。 得到大小计算错误,你打开一个大洞。