gcc棧溢出保護機制:stack-protector

關鍵詞:stack-protector、stack-protector-strong、stack-protector-all等等。html

1. gcc棧保護機制stack-protector簡介

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。

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》。

相關文章
相關標籤/搜索