-Xstack_protector/-Xstack_protector_all [Professional Edition only]


This option specifies generation of a code for detection of stack smashing.

[Specification format]

-Xstack_protector[=num]
-Xstack_protector_all[=num]

 

-

Interpretation when omitted

A code for detection of stack smashing is not generated.

[Detailed description]

-

This option generates a code for detection of stack smashing at the entry and end of a function. A code for detection of stack smashing indicates the instructions for executing the three processes shown below.

(1) A 4-byte area is allocated just before the local variable area (in the direction towards address 0xFFFFFFFF) at the entry to a function, and the value specified by num is stored in the allocated area.

(2) At the end of the function, whether the 4-byte area in which num was stored has been rewritten is checked.

(3) If the value has been rewritten in (2), the __stack_chk_fail function is called as the stack has been smashed.

-

A decimal number from 0 to 4294967295 should be specified in num. If the specification of num is omitted, the compiler automatically specifies the number.

-

The __stack_chk_fail function needs to be defined by the user and the processing to be executed upon detection of stack smashing should be written. Note the following items when defining the __stack_chk_fail function.

-

The only possible type of return value is void and the __stack_chk_fail function does not have formal parameters.

-

It is prohibited to call the __stack_chk_fail function as a normal function.

-

The __stack_chk_fail function is not subject to generating a code for detection of stack smashing due to the -Xstack_protector and -Xstack_protector_all options and #pragma stack_protector.

-

Prevent returning to the caller, that is, the function where stack smashing was detected by taking measures such as calling abort() in the __stack_chk_fail function to terminate the program.

-

When calling another function in the __stack_chk_fail function, note that stack smashing is not detected recursively in the function that was called.

-

If -Xstack_protector is specified, this option generates a code for detection of stack smashing for only functions having a structure, union, or array that exceeds eight bytes as a local variable. If -Xstack_protector_all is specified, this option generates a code for detection of stack smashing for all functions.

-

If these options are used simultaneously with #pragma stack_protector, the specification by #pragma stack_protector becomes valid.

-

Even though this option is specified, a code for detection of stack smashing is not generated for the functions for which one of the following #pragma directives is specified.

#pragma inline, inline keyword, #pragma inline_asm, #pragma no_stack_protector

[Example of use]

-

C source

#include <stdio.h>
#include <stdlib.h>
 
void f1()   // Sample program in which the stack is smashed
{
    volatile char str[10];
    int i;
    for (i = 0; i <= 10; i++){
      str[i] = i; // Stack is smashed when i=10
    }
}
 
void __stack_chk_fail(void)
{
    printf("stack is broken!");
    abort();
}

 

-

Output codes
When compilation is performed with -Xstack_protector=1234 specified.

_f1:
      .stack _f1 = 16
      add 0xFFFFFFF0, r3
       movea 0x000004D2, r0, r1  ; The specified <number> 1234 is stored in the stack area. 
      st.w r1, 0x0000000C[r3]  
      mov 0x00000000, r2
      br9 .BB.LABEL.1_2
.BB.LABEL.1_1:  ; bb
      movea 0x00000002, r3, r5
      add r2, r5
      st.b r2, 0x00000000[r5]
      add 0x00000001, r2
.BB.LABEL.1_2:  ; bb7
      cmp 0x0000000B, r2
      blt9 .BB.LABEL.1_1
.BB.LABEL.1_3:  ; return
      ld.w 0x0000000C[r3], r1   ; Data is loaded from the location where <number>
      movea 0x000004D2, r0, r12 ; was stored at the entry to a function and
      cmp r12, r1               ; it is compared with the specified <number> 1234.
      bnz9 .BB.LABEL.1_5        ; If they do not match, a branch occurs.
.BB.LABEL.1_4:  ; return
      dispose 0x00000010, 0x00000000, [r31]
.BB.LABEL.1_5:  ; return
      br9 ___stack_chk_fail     ; __stack_chk_fail is called.
 
___stack_chk_fail:
      .stack ___stack_chk_fail = 4
      prepare 0x00000001, 0x00000000
      mov #.STR.1, r6
      jarl _printf, r31
      jarl _abort, r31
      dispose 0x00000000, 0x00000001, [r31]