C++ 何时以及如何使用 GCC 的堆栈保护功能?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1629685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When and how to use GCC's stack protection feature?
提问by Guillaume
I have enabled the -Wstack-protector
warning when compiling the project I'm working on (a commercial multi-platform C++ game engine, compiling on Mac OS X 10.6 with GCC 4.2).
This flag warns about functions that will not be protected against stack smashing even though -fstack-protector
is enabled.
GCC emits some warnings when building the project:
我-Wstack-protector
在编译我正在处理的项目(一个商业多平台 C++ 游戏引擎,在 Mac OS X 10.6 和 GCC 4.2 上编译)时启用了警告。此标志警告即使-fstack-protector
启用了也不会受到堆栈粉碎保护的函数。GCC 在构建项目时发出一些警告:
not protecting function: no buffer at least 8 bytes long
not protecting local variables: variable length buffer
不保护功能:没有至少 8 个字节长的缓冲区
不保护局部变量:可变长度缓冲区
For the first warning, I found that it is possible to adjust the minimum size a buffer must have when used in a function, for this function to be protected against stack smashing: --param ssp-buffer-size=X
can be used, where X is 8 by default and can be as low as 1.
对于第一个警告,我发现可以调整在函数中使用时缓冲区必须具有的最小大小,以保护该函数免受堆栈粉碎:--param ssp-buffer-size=X
可以使用,其中 X 默认为 8 并且可以作为低至 1。
For the second warning, I can't suppress its occurrences unless I stop using -Wstack-protector
.
对于第二个警告,除非我停止使用-Wstack-protector
.
- When should
-fstack-protector
be used? (as in, for instance, all the time during dev, or just when tracking bugs down?) - When should
-fstack-protector-all
be used? - What is
-Wstack-protector
telling me? Is it suggesting that I decrease the buffer minimum size? - If so, are there any downsides to putting the size to 1?
- It appears that
-Wstack-protector
is not the kind of flag you want enabled at all times if you want a warning-free build. Is this right?
- 应该
-fstack-protector
什么时候使用?(例如,在开发过程中的所有时间,或者只是在跟踪错误时?) - 应该
-fstack-protector-all
什么时候使用? - 什么是
-Wstack-protector
告诉我?是否建议我减少缓冲区的最小大小? - 如果是这样,将大小设置为 1 有什么缺点吗?
-Wstack-protector
如果您想要无警告构建,这似乎不是您想要始终启用的那种标志。这是正确的吗?
回答by brantgurga
Stack-protection is a hardening strategy, not a debugging strategy. If your game is network-aware or otherwise has data coming from an uncontrolled source, turn it on. If it doesn't have data coming from somewhere uncontrolled, don't turn it on.
堆栈保护是一种加固策略,而不是调试策略。如果您的游戏具有网络感知能力或数据来自不受控制的来源,请将其打开。如果它没有来自不受控制的地方的数据,请不要打开它。
Here's how it plays out: If you have a bug and make a buffer change based on something an attacker can control, that attacker can overwrite the return address or similar portions of the stack to cause it to execute their code instead of your code. Stack protection will abort your program if it detects this happening. Your users won't be happy, but they won't be hacked either. This isn't the sort of hacking that is about cheating in the game, it's the sort of hacking that is about someone using a vulnerability in your code to create an exploit that potentially infects your user.
它是这样执行的:如果您有错误并根据攻击者可以控制的内容更改缓冲区,则该攻击者可以覆盖返回地址或堆栈的类似部分,以使其执行他们的代码而不是您的代码。如果堆栈保护检测到这种情况发生,它将中止您的程序。您的用户不会高兴,但他们也不会被黑客入侵。这不是一种关于在游戏中作弊的黑客行为,而是一种关于某人使用您代码中的漏洞来创建可能感染您的用户的漏洞的黑客行为。
For debugging-oriented solutions, look at things like mudflap.
对于面向调试的解决方案,请查看诸如 mudflap 之类的东西。
As to your specific questions:
至于你的具体问题:
- Use stack protector if you get data from uncontrolled sources. The answer to this is probably yes. So use it. Even if you don't have data from uncontrolled sources, you probably will eventually or already do and don't realize it.
Stack protections for all buffers can be used if you want extra protection in exchange for some performance hit. From gcc4.4.2 manual:
-fstack-protector
Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits.
-fstack-protector-all
Like -fstack-protector except that all functions are protected.
The warnings tell you what buffers the stack protection can't protect.
- It is not necessarily suggesting you decrease your minimum buffer size, and at a size of 0/1, it is the same as stack-protector-all. It is only pointing it out to you so that you can, if you decide redesign the code so that buffer is protected.
- No, those warnings don't represent issues, they just point out information to you. Don't use them regularly.
- 如果您从不受控制的来源获取数据,请使用堆栈保护器。这个问题的答案可能是肯定的。所以使用它。即使您没有来自不受控制的来源的数据,您可能最终或已经这样做了,但没有意识到这一点。
如果您想要额外的保护以换取某些性能损失,则可以使用所有缓冲区的堆栈保护。从gcc4.4.2 手册:
-fstack-protector
发出额外的代码来检查缓冲区溢出,例如堆栈粉碎攻击。这是通过向具有易受攻击对象的函数添加保护变量来完成的。这包括调用 alloca 的函数,以及缓冲区大于 8 字节的函数。守卫在进入函数时初始化,然后在函数退出时检查。如果防护检查失败,则会打印错误消息并退出程序。
-fstack-protector-all
与 -fstack-protector 类似,只是所有功能都受到保护。
警告告诉您堆栈保护无法保护的缓冲区。
- 不一定建议您减小最小缓冲区大小,大小为 0/1 时,它与 stack-protector-all 相同。如果您决定重新设计代码以保护缓冲区,它只是向您指出它,以便您可以。
- 不,这些警告不代表问题,它们只是向您指出信息。不要经常使用它们。
回答by MSalters
You indeed should not care about the warning for normal builds. It's really more of an informational message. I hope it's obvious that you do have an inherent security concern with variable-sized buffers on the stack; get the size calculation wrong and you're opening a big hole.
您确实不应该关心正常构建的警告。这实际上更像是一条信息性消息。我希望很明显,您确实对堆栈上的可变大小缓冲区存在固有的安全问题;把尺寸计算错了,你打开了一个大洞。