關鍵詞:stack-protector、stack-protector-strong、stack-protector-all等等。html
gcc提供了棧保護機制stack-protector。關於stack-protector包含三個選項,分別是stack-protector、stack-protector-all、stack-protector-strong、stack-protector-explicit四種。linux
關於stack-protector原理、實現、效果、侷限參考《GCC 中的編譯器堆棧保護技術》。數組
gcc中對這幾種選項的介紹以下:緩存
-Wstack-protector This option is only active when -fstack-protector is active. It warns about functions that are not protected against stack smashing. -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.
-fstack-protector-strong Like -fstack-protector but includes additional functions to be protected --- those that have local array definitions, or have references to local frame addresses. -fstack-protector-explicit Like -fstack-protector but only protects those functions which have the "stack_protect" attribute.
stack-protector:保護函數中經過alloca()分配緩存以及存在大於8字節的緩存。缺點是保護能力有限。函數
stack-protector-all:保護全部函數的棧。缺點是增長不少額外棧空間,增長程序體積。post
stack-protector-strong:在stack-protector基礎上,增長本地數組、指向本地幀棧地址空間保護。性能
stack-protector-explicit:在stack-protector基礎上,增長程序中顯式屬性"stack_protect"空間。測試
若是要中止使用stack-protector功能,須要加上-fno-stack-protector。url
stack-protector性能:stack-protector > stack-protector-strong > stack-protector-all。spa
stack-protector覆蓋範圍:stack-protector < stack-protector-strong < stack-protector-all。
針對stack-protector的測試,主要對比stack-protector、stack-protector-strong、stack-protector-all三個選項的區別。
#include <string.h> #include <stdio.h> int main(void) { char array[2] = {0}; strcpy(array, "stackwilloverflow"); return 0; }
分別使用以下編譯選項:(1) gcc stack.c -o stack -ggdb -fstack-protector、(2)gcc stack.c -o stack -ggdb -fstack-protector-strong、(3)gcc stack.c -o stack -ggdb -fstack-protector-all。
(1)未能檢查出棧溢出,(2)、(3)都檢查出了stack smashing detected。結論:能夠看出stack-protector-strong和stack-protector-all相對於stack-protector更多的檢測了棧溢出。
*** stack smashing detected ***: ./stack terminated
Aborted (core dumped)
查看core文件的bt full,能夠勘測處發生棧溢出的點在array。
... #3 0x000014653e07915c in __GI___fortify_fail (msg=<optimized out>, msg@entry=0x14653e0ef481 "stack smashing detected") at fortify_fail.c:37 do_abort = 1 #4 0x000014653e079100 in __stack_chk_fail () at stack_chk_fail.c:28 No locals. #5 0x00000000004005a1 in main () at stack.c:11 array = "st"
修改array大小超過8字節以後,從新使用stack-protector進行測試。結論:當數組大小超過8字節事後,stack-protector才能檢測出棧溢出。
#include <string.h> #include <stdio.h> int main(void) { char array[10] = {0}; strcpy(array, "stackwilloverflowoooooooooo"); return 0; }
發現了stack smashing:
*** stack smashing detected ***: ./stack terminated
Aborted (core dumped)
gdb查看backtrace以下:
... #3 0x000015062304c15c in __GI___fortify_fail (msg=<optimized out>, msg@entry=0x1506230c2481 "stack smashing detected") at fortify_fail.c:37 do_abort = 1 #4 0x000015062304c100 in __stack_chk_fail () at stack_chk_fail.c:28 No locals. #5 0x00000000004005b8 in main () at stack.c:11 array = "stackwillo"
首先須要定義HAVE_CC_STACKPROTECTOR,而後經過make menuconfig進行配置。
路徑爲General setup->Stack Protector buffer overflow detection。
參考文檔:《stack-protector-strong》、《-fstack-protector-strong》、《"Strong" stack protection for GCC》。