轉自:https://www.cnblogs.com/arnoldlu/p/11630979.html
關鍵詞:stack-protector、stack-protector-strong、stack-protector-all等等。
1. gcc棧保護機制stack-protector簡介
gcc提供了棧保護機制stack-protector。關於stack-protector包含三個選項,分別是stack-protector、stack-protector-all、stack-protector-strong、stack-protector-explicit四種。
關於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:保護所有函數的棧。缺點是增加很多額外棧空間,增加程序體積。
stack-protector-strong:在stack-protector基礎上,增加本地數組、指向本地幀棧地址空間保護。
stack-protector-explicit:在stack-protector基礎上,增加程序中顯式屬性"stack_protect"空間。
如果要停止使用stack-protector功能,需要加上-fno-stack-protector。
stack-protector性能:stack-protector > stack-protector-strong > stack-protector-all。
stack-protector覆蓋范圍:stack-protector < stack-protector-strong < stack-protector-all。
2. stack-protector測試
針對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"
3. 內核中使用stack-protector
首先需要定義HAVE_CC_STACKPROTECTOR,然后通過make menuconfig進行配置。
路徑為General setup->Stack Protector buffer overflow detection。
參考文檔:《stack-protector-strong》、《-fstack-protector-strong》、《"Strong" stack protection for GCC》。