何时以及如何使用GCC的堆栈保护功能?
-
06-07-2019 - |
题
我在编译正在处理的项目时启用了 -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
,否则我无法抑制它的出现。
- 什么时候应该使用
-fstack-protector
? (例如,在开发期间的所有时间,或者只是在跟踪错误时?) - 什么时候应该使用
-fstack-protector-all
? - 什么是
-Wstack-protector
告诉我?它是否暗示我减少缓冲区最小尺寸? - 如果是这样,将尺寸设为1有什么缺点吗?
- 如果您想要无警告构建,
-Wstack-protector
似乎不是您想要始终启用的那种标志。这是对的吗?
醇>
解决方案
堆栈保护是一种强化策略,而不是调试策略。如果您的游戏具有网络感知能力,或者其他数据来自不受控制的来源,请将其打开。如果没有来自不受控制的地方的数据,请不要打开它。
以下是它如何发挥作用:如果你有一个bug并根据攻击者可以控制的东西进行缓冲区更改,那么攻击者可以覆盖返回地址或堆栈的类似部分,使其执行代码而不是你的代码码。如果检测到这种情况,堆栈保护将中止您的程序。您的用户不会满意,但他们也不会被黑客攻击。这不是那种在游戏中作弊的黑客攻击,而是一种黑客攻击,即使用代码中的漏洞创建可能会感染用户的漏洞。
对于面向调试的解决方案,请查看mudflap等内容。
关于您的具体问题:
- 如果从不受控制的来源获取数据,请使用堆栈保护程序。答案可能是肯定的。所以使用它。即使您没有来自不受控制的来源的数据,您可能最终或已经做过而且没有意识到这一点。
-
如果您需要额外保护以换取某些性能损失,可以使用所有缓冲区的堆栈保护。来自 gcc4.4.2手册:
-fstack-保护
发出额外的代码来检查缓冲区溢出,例如堆栈粉碎攻击。这是通过向具有易受攻击对象的函数添加保护变量来完成的。这包括调用alloca的函数,以及大于8字节的缓冲区的函数。输入功能时会初始化防护装置,然后在功能退出时进行检查。如果防护检查失败,则会打印一条错误消息并退出程序。
-fstack保护器-所有
与-fstack-protector类似,但所有功能都受到保护。
-
警告告诉您堆栈保护无法保护的缓冲区。
- 不一定建议您减小最小缓冲区大小,并且大小为0/1时,它与stack-protector-all相同。如果您决定重新设计代码以便缓冲区受到保护,它只会向您指出,以便您可以这样做。
- 不,这些警告不代表问题,他们只是向您指出信息。不要经常使用它们。 醇>
其他提示
你确实不应该关心正常构建的警告。这更像是一条信息性的信息。我希望很明显你对堆栈中可变大小的缓冲区确实存在固有的安全问题;得到大小计算错误,你正在打开一个大洞。