最近在mips-openwrt的工具链中交叉编译可执行程序时,出现了以下的错误:
undefined reference to `__stack_chk_guard'
undefined reference to `__stack_chk_fail'
百度一下,得知这个错误的引起是因为启用了Stack Guard堆栈保护,什么是堆栈保护呢?如下:
Stack Guard 是第一个使用 Canaries 探测的堆栈保护实现,它于 1997 年作为 GCC 的一个扩展发布。最初版本的 Stack Guard 使用 0x00000000 作为 canary word。尽管很多人建议把 Stack Guard 纳入 GCC,作为 GCC 的一部分来提供堆栈保护。但实际上,GCC 3.x 没有实现任何的堆栈保护。直到 GCC 4.1 堆栈保护才被加入,并且 GCC4.1 所采用的堆栈保护实现并非 Stack Guard,而是 Stack-smashing Protection(SSP,又称 ProPolice)。
SSP 在 Stack Guard 的基础上进行了改进和提高。它是由 IBM 的工程师 Hiroaki Rtoh 开发并维护的。与 Stack Guard 相比,SSP 保护函数返回地址的同时还保护了栈中的 EBP 等信息。此外,SSP 还有意将局部变量中的数组放在函数栈的高地址,而将其他变量放在低地址。这样就使得通过溢出一个数组来修改其他变量(比如一个函数指针)变得更为困难。
-fstack-protector:
启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。
-fstack-protector-all:
启用堆栈保护,为所有函数插入保护代码。
-fno-stack-protector:
禁用堆栈保护。
那么我们可以知道堆栈保护是通过宏定义-fstack-protector来启用的,当然在makefile里面我是有用到这个宏定义的。
如果去掉这个宏定义或者加上-fno-stack-protector这个宏,yes,清静了,没有错误了。
但到这里还不能结束,我们要探究一下为什么在mipsel-openwrt-linux-gcc里面是无法使用Stack Guard堆栈保护。
我们知道Stack Guard是需要GCC 支持libssp的,我们就去openwrt源码看一下是否存在libssp这个库
发现在build_dir/toolchain-mipsel_24kec+dsp_gcc-4.6-linaro_uClibc-0.9.33.2/gcc-linaro-4.6-2013.05/libssp目录下是存在libssp,但是我们在make menuconfig里却找不到可配置libssp的选项。
现在只能google一把
是的,由于ssp库不能很好支持全平台,并没有把ssp默认编译。
问题已经解决,不想去折腾openssh了,如果不用Stack Guard进行堆栈保护,只能自己代码保护了,也不用这个高级玩意了。
楼主只能默默去掉了-fstack-protector-all