gcc 的 -fstack-protector 选项如何防止堆栈粉碎?
Posted
技术标签:
【中文标题】gcc 的 -fstack-protector 选项如何防止堆栈粉碎?【英文标题】:How does gcc's -fstack-protector option prevent stack smashing? 【发布时间】:2018-11-30 00:02:58 【问题描述】:我遇到了堆栈崩溃问题,我很难找到原因。堆栈粉碎错误只是偶尔发生,并且仅在程序执行结束时发生。当我使用带有 gcc 的 'fstack-protector' 选项编译它时,它也完全停止发生。我想知道使用“fstack-protector”选项是否是一个实际的解决方案,或者我只是在隐藏问题?我会发布代码,但它有 3000 行长,我不确定代码的哪一部分负责。
【问题讨论】:
是的,你在隐藏问题。-fstack-protector
应该将可利用的错误转变为即时崩溃,而不是完全防止堆栈损坏。如果程序在使用-fstack-protector
编译时停止崩溃,那么它只是让错误受到干扰而无法显现。请改用valgrind
。
我建议使用-fsanitize=address
编译并运行程序。它比 valgrind 更擅长分析堆栈,因为它知道堆栈上的实际变量,并且它可以告诉您堆栈上的数组访问何时溢出到另一个堆栈变量中。 github.com/google/sanitizers/wiki/…
【参考方案1】:
此选项不防止堆栈粉碎,而是检测它并停止程序。
来自 gcc 手册页:
-fstack-protector
发出额外的代码来检查缓冲区溢出,例如堆栈 粉碎攻击。这是通过添加一个保护变量来完成的 具有易受攻击对象的功能。这包括以下功能 调用“alloca”,以及缓冲区大于 8 字节的函数。这 输入函数时初始化守卫,然后检查 当函数退出时。如果保护检查失败,则会出现错误消息 打印出来,程序退出。
您仍然有溢出问题,但添加保护变量显然掩盖了问题。如果您在valgrind 下运行程序,它应该能够检测到正在发生的事情。
【讨论】:
以上是关于gcc 的 -fstack-protector 选项如何防止堆栈粉碎?的主要内容,如果未能解决你的问题,请参考以下文章