Stack-protector-strong

Source: Internet
Author: User

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 kernel Security Update introducesstack-protector-strong.

Earlier is-fstack-protectorAnd-fstack-protector-allOption, but they both have disadvantages. The Chrome OS compiler team visually tested obsessive-compulsive disorder and designedstack-protector-strong.

-Fstack-disadvantages of Protector

Only functions that use a char array of> = 8 bytes (-Param = SSP-buffer-size = N, default n = 8) provide protection, so the protection capability is limited.

-Fstack-protector-all disadvantages

All functions will be added for detection. 1) it will increase the program size. 2) it will occupy the stack space, especially when the kernel stack space is fixed. This is not a good design.

-Fstack-protector-strong

Let's take a look.stack-protector-strongOption, which has its filtering principle for whether to add canary to the function. In summary, there are several:

  1. When the local variable's ** address ** is used as part of the right value of the value assignment expression, or as a function parameter
  2. When the local variable is an array (or contains the Union type of the array), regardless of the array size and type
  3. Use the Register Type local variable (*) (uses register local variables)

3rd points failed to be verified. What may be wrong?

Through the assembly code, compare:

[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-strongThe compilation result is as follows:

201710000004005ca <a >:# the local variable address is used as the function parameter 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 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 callq 400470 <[email protected]> 400608: C9 leaveq 400609: c3 retq 000000000040060a <B >:# when the register type variable is used, why? 40060a: 55 push % RBP 40060b: 48 89 E5 mov % RSP, % RBP 40060e: 5D pop % RBP 40060f: C3 retq 0000000000400610 <D >:# the array length is 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 callq 400470 <[email protected]> 400645: C9 leaveq 400646: C3 retq 0000000000400647 <e >:# the array type is 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 callq 400470 <[email protected]> 400692: C9 leaveq 400693: c3 retq 0000000000400694 <F >:# the local variable is part of the left value of the value assignment expression. 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 callq 400470 <[email protected]> 4006d2: C9 leaveq 4006d3: C3 retq

By default, the-fstack-Protector option is used during compilation. The result is as follows:

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   

In the above cases, Canary is not inserted in the function. Observe carefully-fstack-protector-stongProtected objects may be used to execute arbitrary code. For example, if an object is assigned a value or a function parameter is a function pointer, the modified value will execute arbitrary code.

Canary impact on the system

From the Linux kernel 3.14, a new compilation option config_cc_stackprotector_strong is added for-fstack-protector-strong. The original option config_cc_stackprotector (corresponding to-fstack-protector) is changed to config_cc_stackprotector_regular.

The following is the kernel comparison data compiled by the default x86_64 platform.

Compilation options Code segment size (in bytes) Number of protected functions/total number of functions
No stack Protector 11430641 0/36110
Config_cc_stackprotector_regular 11468490 (more than 0.33%) 1015/36110 (2.81%)
Config_cc_stackprotector_strong 11692790 (more than 2.24%) 7401/36110 (20.5%)

It can be seen that compared to-fstack-protector-all, 20.5% is already good, and there is a good compromise between performance and security.

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

Stack-protector-strong

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.