stack-protector-strong

來源:互聯網
上載者:User

標籤:art   編譯器   length   can   cat   buffer   設計   like   pop   

Improve protection against stack buffer overflows

Much like its predecessor, stack-protector, stack-protector-strong protects against stack buffer overflows, but additionally provides coverage for more array types, as the original only protected character arrays. Stack-protector-strong was implemented by Han Shen and added to the gcc 4.9 compiler.

Android 7.0 的核心安全更新中,引入了 stack-protector-strong

更早的是 -fstack-protector 與 -fstack-protector-all選項,但它們各自都有缺點,Chrome OS 的編譯器團隊目測有強迫症,設計了 stack-protector-strong

-fstack-protector 的缺點

僅對使用>=8位元組(–param=ssp-buffer-size=N, 預設N=8)的char數組的函數提供保護,因此其保護能力有限。

-fstack-protector-all 的缺點

所有函數都會加入檢測,1)會增加程式體積,2)佔用棧空間,尤其核心棧空間固定的情況;可以認為這都不是好的設計。

-fstack-protector-strong

再來看一下 stack-protector-strong 選項,它對是否在函數中加入canary有其篩選原則,總結起來有幾條:

  1. 當本地變數的***地址***,作為賦值運算式右值 的一部分,或作為函數參數
  2. 當本地變數是數組(或包含數組的union 類型),不管數組大小與類型
  3. 使用 register 類型的本地變數(*)(uses register local variables)

第3點未能驗證,可能理解有誤?

通過彙編代碼,對比一下:

[email protected]:~/exploits/test$ cat register.c #include <stdio.h>void c (long a){        printf ("%ld\n", a);}/* local variable’s address used as part of function argument */int a () {        int a = 10;        c((long)&a);}int b () {        register int *foo asm ("r12");}/* regardless of array length */void d () {        char str[2] = {‘A‘};}/* regardless of array type */void e () {        int a[10];        int i;        for (i = 0; i < 10; i++)                a[i] = ‘A‘;}/* local variable’s address used as part of the right hand side of an assignment */void f (int *b) {        int a = 10;        b = &a;}int main (){}

stack-protector-strong選項編譯結果如下:

00000000004005ca <a>:    #本地變數地址作為函數參數  4005ca:       55                      push   %rbp  4005cb:       48 89 e5                mov    %rsp,%rbp  4005ce:       48 83 ec 10             sub    $0x10,%rsp  4005d2:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax  4005d9:       00 00   4005db:       48 89 45 f8             mov    %rax,-0x8(%rbp)  4005df:       31 c0                   xor    %eax,%eax  4005e1:       c7 45 f4 0a 00 00 00    movl   $0xa,-0xc(%rbp)  4005e8:       48 8d 45 f4             lea    -0xc(%rbp),%rax  4005ec:       48 89 c7                mov    %rax,%rdi  4005ef:       e8 b2 ff ff ff          callq  4005a6 <c>  4005f4:       48 8b 55 f8             mov    -0x8(%rbp),%rdx  4005f8:       64 48 33 14 25 28 00    xor    %fs:0x28,%rdx  4005ff:       00 00   400601:       74 05                   je     400608 <a+0x3e>  400603:       e8 68 fe ff ff          callq  400470 <[email protected]>  400608:       c9                      leaveq   400609:       c3                      retq   000000000040060a <b>:    #使用register類型變數,Why未印證?  40060a:       55                      push   %rbp  40060b:       48 89 e5                mov    %rsp,%rbp  40060e:       5d                      pop    %rbp  40060f:       c3                      retq   0000000000400610 <d>:    #數組長度為2  400610:       55                      push   %rbp  400611:       48 89 e5                mov    %rsp,%rbp  400614:       48 83 ec 10             sub    $0x10,%rsp  400618:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax  40061f:       00 00   400621:       48 89 45 f8             mov    %rax,-0x8(%rbp)  400625:       31 c0                   xor    %eax,%eax  400627:       66 c7 45 f0 00 00       movw   $0x0,-0x10(%rbp)  40062d:       c6 45 f0 41             movb   $0x41,-0x10(%rbp)  400631:       48 8b 45 f8             mov    -0x8(%rbp),%rax  400635:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax  40063c:       00 00   40063e:       74 05                   je     400645 <d+0x35>  400640:       e8 2b fe ff ff          callq  400470 <[email protected]>  400645:       c9                      leaveq   400646:       c3                      retq   0000000000400647 <e>:    #數群組類型為int  400647:       55                      push   %rbp  400648:       48 89 e5                mov    %rsp,%rbp  40064b:       48 83 ec 40             sub    $0x40,%rsp  40064f:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax  400656:       00 00   400658:       48 89 45 f8             mov    %rax,-0x8(%rbp)  40065c:       31 c0                   xor    %eax,%eax  40065e:       c7 45 cc 00 00 00 00    movl   $0x0,-0x34(%rbp)  400665:       eb 11                   jmp    400678 <e+0x31>  400667:       8b 45 cc                mov    -0x34(%rbp),%eax  40066a:       48 98                   cltq     40066c:       c7 44 85 d0 41 00 00    movl   $0x41,-0x30(%rbp,%rax,4)  400673:       00   400674:       83 45 cc 01             addl   $0x1,-0x34(%rbp)  400678:       83 7d cc 09             cmpl   $0x9,-0x34(%rbp)  40067c:       7e e9                   jle    400667 <e+0x20>  40067e:       48 8b 45 f8             mov    -0x8(%rbp),%rax  400682:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax  400689:       00 00   40068b:       74 05                   je     400692 <e+0x4b>  40068d:       e8 de fd ff ff          callq  400470 <[email protected]>  400692:       c9                      leaveq   400693:       c3                      retq   0000000000400694 <f>:    #本地變數作為賦值運算式左值的一部分  400694:       55                      push   %rbp  400695:       48 89 e5                mov    %rsp,%rbp  400698:       48 83 ec 20             sub    $0x20,%rsp  40069c:       48 89 7d e8             mov    %rdi,-0x18(%rbp)  4006a0:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax  4006a7:       00 00   4006a9:       48 89 45 f8             mov    %rax,-0x8(%rbp)  4006ad:       31 c0                   xor    %eax,%eax  4006af:       c7 45 f4 0a 00 00 00    movl   $0xa,-0xc(%rbp)  4006b6:       48 8d 45 f4             lea    -0xc(%rbp),%rax  4006ba:       48 89 45 e8             mov    %rax,-0x18(%rbp)  4006be:       48 8b 45 f8             mov    -0x8(%rbp),%rax  4006c2:       64 48 33 04 25 28 00    xor    %fs:0x28,%rax  4006c9:       00 00   4006cb:       74 05                   je     4006d2 <f+0x3e>  4006cd:       e8 9e fd ff ff          callq  400470 <[email protected]>  4006d2:       c9                      leaveq   4006d3:       c3                      retq   

預設編譯時間,使用的是-fstack-protector選項,其結果如下:

000000000040055a <a>:  40055a:       55                      push   %rbp  40055b:       48 89 e5                mov    %rsp,%rbp  40055e:       48 83 ec 10             sub    $0x10,%rsp  400562:       c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)  400569:       48 8d 45 fc             lea    -0x4(%rbp),%rax  40056d:       48 89 c7                mov    %rax,%rdi  400570:       e8 c1 ff ff ff          callq  400536 <c>  400575:       c9                      leaveq   400576:       c3                      retq   0000000000400577 <b>:  400577:       55                      push   %rbp  400578:       48 89 e5                mov    %rsp,%rbp  40057b:       5d                      pop    %rbp  40057c:       c3                      retq   000000000040057d <d>:  40057d:       55                      push   %rbp  40057e:       48 89 e5                mov    %rsp,%rbp  400581:       66 c7 45 f0 00 00       movw   $0x0,-0x10(%rbp)  400587:       c6 45 f0 41             movb   $0x41,-0x10(%rbp)  40058b:       5d                      pop    %rbp  40058c:       c3                      retq   000000000040058d <e>:  40058d:       55                      push   %rbp  40058e:       48 89 e5                mov    %rsp,%rbp  400591:       c7 45 cc 00 00 00 00    movl   $0x0,-0x34(%rbp)  400598:       eb 11                   jmp    4005ab <e+0x1e>  40059a:       8b 45 cc                mov    -0x34(%rbp),%eax  40059d:       48 98                   cltq     40059f:       c7 44 85 d0 41 00 00    movl   $0x41,-0x30(%rbp,%rax,4)  4005a6:       00   4005a7:       83 45 cc 01             addl   $0x1,-0x34(%rbp)  4005ab:       83 7d cc 09             cmpl   $0x9,-0x34(%rbp)  4005af:       7e e9                   jle    40059a <e+0xd>  4005b1:       5d                      pop    %rbp  4005b2:       c3                      retq   00000000004005b3 <f>:  4005b3:       55                      push   %rbp  4005b4:       48 89 e5                mov    %rsp,%rbp  4005b7:       48 89 7d e8             mov    %rdi,-0x18(%rbp)  4005bb:       c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)  4005c2:       48 8d 45 fc             lea    -0x4(%rbp),%rax  4005c6:       48 89 45 e8             mov    %rax,-0x18(%rbp)  4005ca:       5d                      pop    %rbp  4005cb:       c3                      retq   

以上幾種情況,函數內均未插入canary。仔細觀察 -fstack-protector-stong 保護的對象,其實都是有可能被利用來執行任意代碼的,比如若被賦值對象,或函數參數是一個函數指標,則修改其值會執行任意代碼。

canary 對系統影響

Linux 從3.14核心開始,為-fstack-protector-strong增加了一個新的編譯選項CONFIG_CC_STACKPROTECTOR_STRONG,並且原有選項CONFIG_CC_STACKPROTECTOR(對應-fstack-protector)修改為CONFIG_CC_STACKPROTECTOR_REGULAR。

以下是x86_64平台預設選項編譯的核心對比資料。

編譯選項 程式碼片段大小(位元組) 被保護函數個數 / 函數總數
no stack protector 11430641 0 / 36110
CONFIG_CC_STACKPROTECTOR_REGULAR 11468490 (+0.33%) 1015 / 36110 (2.81%)
CONFIG_CC_STACKPROTECTOR_STRONG 11692790 (+2.24%) 7401 / 36110 (20.5%)

可以看出比起-fstack-protector-all,20.5%已經不錯,在效能與安全之間找到了很好的折衷。

參考 :https://outflux.net/blog/archives/2014/01/27/fstack-protector-strong/

stack-protector-strong

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.